resolve warnings
This commit is contained in:
		
							parent
							
								
									a34e0bbb5d
								
							
						
					
					
						commit
						8620a452a3
					
				| @ -9,11 +9,11 @@ import { loadUser } from "./actions/authActions"; | |||||||
| 
 | 
 | ||||||
| import "./App.css"; | import "./App.css"; | ||||||
| 
 | 
 | ||||||
| import { ThemeProvider, createMuiTheme } from "@material-ui/core/styles"; | import { ThemeProvider, createTheme } from "@material-ui/core/styles"; | ||||||
| 
 | 
 | ||||||
| import Content from "./components/Content"; | import Content from "./components/Content"; | ||||||
| 
 | 
 | ||||||
| const theme = createMuiTheme({ | const theme = createTheme({ | ||||||
|   palette: { |   palette: { | ||||||
|     primary: { |     primary: { | ||||||
|       main: "#4EAF47", |       main: "#4EAF47", | ||||||
|  | |||||||
| @ -13,10 +13,10 @@ import SaveIcon from "./SaveIcon"; | |||||||
| import store from "../../store"; | import store from "../../store"; | ||||||
| 
 | 
 | ||||||
| const CodeEditor = (props) => { | const CodeEditor = (props) => { | ||||||
|   const [fileHandle, setFileHandle] = useState(); |   //const [filehandle, setFileHandle] = useState();
 | ||||||
|   const [fileContent, setFileContent] = useState(""); |   const [fileContent, setFileContent] = useState(""); | ||||||
|   const [progress, setProgress] = useState(false); |   const [progress, setProgress] = useState(false); | ||||||
|   const [id, setId] = useState(""); |   // const [id, setId] = useState("");
 | ||||||
|   const [open, setOpen] = useState(false); |   const [open, setOpen] = useState(false); | ||||||
|   const [error, setError] = useState(""); |   const [error, setError] = useState(""); | ||||||
|   const editorRef = useRef(null); |   const editorRef = useRef(null); | ||||||
| @ -24,20 +24,6 @@ const CodeEditor = (props) => { | |||||||
|   const [time, setTime] = useState(null); |   const [time, setTime] = useState(null); | ||||||
|   const [value, setValue] = useState(""); |   const [value, setValue] = useState(""); | ||||||
|   const [resetDialog, setResetDialog] = useState(false); |   const [resetDialog, setResetDialog] = useState(false); | ||||||
|   const [defaultValue, setDefaultValue] = useState( |  | ||||||
|     localStorage.getItem("ArduinoCode") |  | ||||||
|       ? localStorage.getItem("ArduinoCode") |  | ||||||
|       : ` |  | ||||||
| #include <senseBoxIO.h> //needs to be always included
 |  | ||||||
| 
 |  | ||||||
| void setup () { |  | ||||||
|           |  | ||||||
| } |  | ||||||
|            |  | ||||||
| void loop() { |  | ||||||
|            |  | ||||||
| }` |  | ||||||
|   ); |  | ||||||
| 
 | 
 | ||||||
|   const compile = () => { |   const compile = () => { | ||||||
|     setProgress(true); |     setProgress(true); | ||||||
| @ -60,7 +46,7 @@ void loop() { | |||||||
|         } |         } | ||||||
|         setProgress(false); |         setProgress(false); | ||||||
|         const result = data.data.id; |         const result = data.data.id; | ||||||
|         setId(result); |         //setId(result);
 | ||||||
|         const filename = "sketch"; |         const filename = "sketch"; | ||||||
|         window.open( |         window.open( | ||||||
|           `${process.env.REACT_APP_COMPILER_URL}/download?id=${result}&board=${process.env.REACT_APP_BOARD}&filename=${filename}`, |           `${process.env.REACT_APP_COMPILER_URL}/download?id=${result}&board=${process.env.REACT_APP_BOARD}&filename=${filename}`, | ||||||
| @ -83,7 +69,7 @@ void loop() { | |||||||
| 
 | 
 | ||||||
|   const openIno = async () => { |   const openIno = async () => { | ||||||
|     const [myFileHandle] = await window.showOpenFilePicker(); |     const [myFileHandle] = await window.showOpenFilePicker(); | ||||||
|     setFileHandle(myFileHandle); |     //setFileHandle(myFileHandle);
 | ||||||
| 
 | 
 | ||||||
|     const file = await myFileHandle.getFile(); |     const file = await myFileHandle.getFile(); | ||||||
|     const contents = await file.text(); |     const contents = await file.text(); | ||||||
| @ -187,7 +173,20 @@ void loop() { | |||||||
|               editValue(value); |               editValue(value); | ||||||
|             }} |             }} | ||||||
|             defaultLanguage="cpp" |             defaultLanguage="cpp" | ||||||
|             defaultValue={defaultValue} |             defaultValue={ | ||||||
|  |               localStorage.getItem("ArduinoCode") | ||||||
|  |                 ? localStorage.getItem("ArduinoCode") | ||||||
|  |                 : ` | ||||||
|  |       #include <senseBoxIO.h> //needs to be always included
 | ||||||
|  |        | ||||||
|  |       void setup () { | ||||||
|  |                 | ||||||
|  |       } | ||||||
|  |                  | ||||||
|  |       void loop() { | ||||||
|  |                  | ||||||
|  |       }` | ||||||
|  |             } | ||||||
|             value={fileContent} |             value={fileContent} | ||||||
|             onMount={(editor, monaco) => { |             onMount={(editor, monaco) => { | ||||||
|               editorRef.current = editor; |               editorRef.current = editor; | ||||||
|  | |||||||
| @ -1,179 +1,100 @@ | |||||||
| import React, { Component } from 'react'; | import React, { Component } from "react"; | ||||||
| 
 | 
 | ||||||
| import Breadcrumbs from './Breadcrumbs'; | import Breadcrumbs from "./Breadcrumbs"; | ||||||
| 
 | 
 | ||||||
| import { withRouter } from 'react-router-dom'; | import { withRouter } from "react-router-dom"; | ||||||
| 
 | 
 | ||||||
| import Button from '@material-ui/core/Button'; | import Button from "@material-ui/core/Button"; | ||||||
| import Typography from '@material-ui/core/Typography'; | import Typography from "@material-ui/core/Typography"; | ||||||
| import * as Blockly from 'blockly' | import * as Blockly from "blockly"; | ||||||
| import ReactMarkdown from 'react-markdown'; | import ReactMarkdown from "react-markdown"; | ||||||
| import Container from '@material-ui/core/Container'; | import Container from "@material-ui/core/Container"; | ||||||
| import ExpansionPanel from '@material-ui/core/ExpansionPanel'; | import ExpansionPanel from "@material-ui/core/ExpansionPanel"; | ||||||
| import ExpansionPanelSummary from '@material-ui/core/ExpansionPanelSummary'; | import ExpansionPanelSummary from "@material-ui/core/ExpansionPanelSummary"; | ||||||
| import ExpansionPanelDetails from '@material-ui/core/ExpansionPanelDetails'; | import ExpansionPanelDetails from "@material-ui/core/ExpansionPanelDetails"; | ||||||
| import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||||
| import { faChevronDown } from "@fortawesome/free-solid-svg-icons"; | import { faChevronDown } from "@fortawesome/free-solid-svg-icons"; | ||||||
| import { FaqQuestions } from '../data/faq' | import { FaqQuestions } from "../data/faq"; | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| class Faq extends Component { | class Faq extends Component { | ||||||
|  |   state = { | ||||||
|  |     panel: "", | ||||||
|  |     expanded: false, | ||||||
|  |   }; | ||||||
| 
 | 
 | ||||||
|     state = { |   handleChange = (panel) => { | ||||||
|         panel: '', |     this.setState({ panel: this.state.panel === panel ? "" : panel }); | ||||||
|         expanded: false |   }; | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|  |   componentDidMount() { | ||||||
|  |     // Ensure that Blockly.setLocale is adopted in the component.
 | ||||||
|  |     // Otherwise, the text will not be displayed until the next update of the component.
 | ||||||
| 
 | 
 | ||||||
|     handleChange = (panel) => { |     window.scrollTo(0, 0); | ||||||
|         this.setState({ panel: this.state.panel === panel ? '' : panel }); |     this.forceUpdate(); | ||||||
|     }; |   } | ||||||
| 
 | 
 | ||||||
|     componentDidMount() { |   render() { | ||||||
|         // Ensure that Blockly.setLocale is adopted in the component.
 |     const { panel } = this.state; | ||||||
|         // Otherwise, the text will not be displayed until the next update of the component.
 |     return ( | ||||||
| 
 |       <div> | ||||||
|         window.scrollTo(0, 0) |         <Breadcrumbs | ||||||
|         this.forceUpdate(); |           content={[{ link: this.props.location.pathname, title: "FAQ" }]} | ||||||
|     } |         /> | ||||||
| 
 |         <Container fixed> | ||||||
|     render() { |           <div style={{ margin: "0px 24px 0px 24px" }}> | ||||||
|         const { panel } = this.state; |             <h1>FAQ</h1> | ||||||
|         return ( |             {FaqQuestions().map((object, i) => { | ||||||
|             <div> |               return ( | ||||||
|                 <Breadcrumbs content={[{ link: this.props.location.pathname, title: 'FAQ' }]} /> |                 <ExpansionPanel | ||||||
|                 <Container fixed> |                   expanded={panel === `panel${i}`} | ||||||
|                     <div style={{ margin: '0px 24px 0px 24px' }}> |                   onChange={() => this.handleChange(`panel${i}`)} | ||||||
|                         <h1>FAQ</h1> |                 > | ||||||
|                         {FaqQuestions().map((object, i) => { |                   <ExpansionPanelSummary | ||||||
|                             return ( |                     expandIcon={<FontAwesomeIcon icon={faChevronDown} />} | ||||||
|                                 <ExpansionPanel expanded={panel === `panel${i}`} onChange={() => this.handleChange(`panel${i}`)}> |                   > | ||||||
|                                     <ExpansionPanelSummary |                     <Typography variant="h6">{object.question}</Typography> | ||||||
|                                         expandIcon={ |                   </ExpansionPanelSummary> | ||||||
|                                             <FontAwesomeIcon icon={faChevronDown} /> |                   <ExpansionPanelDetails> | ||||||
|                                         } |                     <Typography> | ||||||
|                                     > |                       <ReactMarkdown | ||||||
|                                         <Typography variant="h6">{object.question}</Typography> |                         className="news" | ||||||
|                                     </ExpansionPanelSummary> |                         allowDangerousHtml="true" | ||||||
|                                     <ExpansionPanelDetails> |                         children={object.answer} | ||||||
|                                         <Typography> |                       ></ReactMarkdown> | ||||||
|                                             <ReactMarkdown className="news" allowDangerousHtml="true" children={object.answer}> |                     </Typography> | ||||||
|                                             </ReactMarkdown> |                   </ExpansionPanelDetails> | ||||||
|                                         </Typography> |                 </ExpansionPanel> | ||||||
|                                     </ExpansionPanelDetails> |               ); | ||||||
|                                 </ExpansionPanel> |             })} | ||||||
|                             ) |             {this.props.button ? ( | ||||||
|                         })} |               <Button | ||||||
|                         { |                 style={{ marginTop: "20px" }} | ||||||
|                             this.props.button ? |                 variant="contained" | ||||||
|                                 <Button |                 color="primary" | ||||||
|                                     style={{ marginTop: '20px' }} |                 onClick={() => { | ||||||
|                                     variant="contained" |                   this.props.history.push(this.props.button.link); | ||||||
|                                     color="primary" |                 }} | ||||||
|                                     onClick={() => { this.props.history.push(this.props.button.link) }} |               > | ||||||
|                                 > |                 {this.props.button.title} | ||||||
|                                     {this.props.button.title} |               </Button> | ||||||
|                                 </Button> |             ) : ( | ||||||
|                                 : |               <Button | ||||||
|                                 <Button |                 style={{ marginTop: "20px" }} | ||||||
|                                     style={{ marginTop: '20px' }} |                 variant="contained" | ||||||
|                                     variant="contained" |                 color="primary" | ||||||
|                                     color="primary" |                 onClick={() => { | ||||||
|                                     onClick={() => { this.props.history.push('/') }} |                   this.props.history.push("/"); | ||||||
|                                 > |                 }} | ||||||
|                                     {Blockly.Msg.button_back} |               > | ||||||
|                                 </Button> |                 {Blockly.Msg.button_back} | ||||||
|                         } |               </Button> | ||||||
|                     </div> |             )} | ||||||
|                 </Container> |           </div> | ||||||
|             </div > |         </Container> | ||||||
|         ); |       </div> | ||||||
|     }; |     ); | ||||||
|  |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export default withRouter(Faq); | export default withRouter(Faq); | ||||||
|                 /* |  | ||||||
| <ExpansionPanel expanded={panel === 'panel1'} onChange={() => this.handleChange('panel1')}> |  | ||||||
| <ExpansionPanelSummary |  | ||||||
| expandIcon={ |  | ||||||
| <FontAwesomeIcon icon={faChevronDown} /> |  | ||||||
| } |  | ||||||
| > |  | ||||||
| <Typography variant="h6">{Blockly.Msg.faq_q1_question}</Typography> |  | ||||||
| </ExpansionPanelSummary> |  | ||||||
| <ExpansionPanelDetails> |  | ||||||
| <Typography> |  | ||||||
| <ReactMarkdown className="news" allowDangerousHtml="true" children={Blockly.Msg.faq_q1_answer}> |  | ||||||
| </ReactMarkdown> |  | ||||||
| </Typography> |  | ||||||
| </ExpansionPanelDetails> |  | ||||||
| </ExpansionPanel> |  | ||||||
| <ExpansionPanel expanded={panel === 'panel2'} onChange={() => this.handleChange('panel2')}> |  | ||||||
| <ExpansionPanelSummary |  | ||||||
| expandIcon={ |  | ||||||
| <FontAwesomeIcon icon={faChevronDown} /> |  | ||||||
| } |  | ||||||
| > |  | ||||||
| <Typography>Frage 2</Typography> |  | ||||||
| </ExpansionPanelSummary> |  | ||||||
| <ExpansionPanelDetails> |  | ||||||
| <Typography> |  | ||||||
| Donec placerat, lectus sed mattis semper, neque lectus feugiat lectus, varius pulvinar |  | ||||||
| diam eros in elit. Pellentesque convallis laoreet laoreet. |  | ||||||
| </Typography> |  | ||||||
| </ExpansionPanelDetails> |  | ||||||
| </ExpansionPanel> |  | ||||||
| <ExpansionPanel expanded={panel === 'panel3'} onChange={() => this.handleChange('panel3')}> |  | ||||||
| <ExpansionPanelSummary |  | ||||||
| expandIcon={ |  | ||||||
| <FontAwesomeIcon icon={faChevronDown} /> |  | ||||||
| } |  | ||||||
| > |  | ||||||
| <Typography>Frage 3</Typography> |  | ||||||
| </ExpansionPanelSummary> |  | ||||||
| <ExpansionPanelDetails> |  | ||||||
| <Typography> |  | ||||||
| Nunc vitae orci ultricies, auctor nunc in, volutpat nisl. Integer sit amet egestas eros, |  | ||||||
| vitae egestas augue. Duis vel est augue. |  | ||||||
| </Typography> |  | ||||||
| </ExpansionPanelDetails> |  | ||||||
| </ExpansionPanel> |  | ||||||
| <ExpansionPanel expanded={panel === 'panel4'} onChange={() => this.handleChange('panel4')}> |  | ||||||
| <ExpansionPanelSummary |  | ||||||
| expandIcon={ |  | ||||||
| <FontAwesomeIcon icon={faChevronDown} /> |  | ||||||
| } |  | ||||||
| > |  | ||||||
| <Typography>Frage 4</Typography> |  | ||||||
| </ExpansionPanelSummary> |  | ||||||
| <ExpansionPanelDetails> |  | ||||||
| <Typography> |  | ||||||
| Nunc vitae orci ultricies, auctor nunc in, volutpat nisl. Integer sit amet egestas eros, |  | ||||||
| vitae egestas augue. Duis vel est augue. |  | ||||||
| </Typography> |  | ||||||
| </ExpansionPanelDetails> |  | ||||||
| </ExpansionPanel> |  | ||||||
| */ |  | ||||||
| 
 |  | ||||||
|                     // {{
 |  | ||||||
|                     //     this.props.button ?
 |  | ||||||
|                     //         <Button
 |  | ||||||
|                     //             style={{ marginTop: '20px' }}
 |  | ||||||
|                     //             variant="contained"
 |  | ||||||
|                     //             color="primary"
 |  | ||||||
|                     //             onClick={() => { this.props.history.push(this.props.button.link) }}
 |  | ||||||
|                     //         >
 |  | ||||||
|                     //             {this.props.button.title}
 |  | ||||||
|                     //         </Button>
 |  | ||||||
|                     //         :
 |  | ||||||
|                     //         <Button
 |  | ||||||
|                     //             style={{ marginTop: '20px' }}
 |  | ||||||
|                     //             variant="contained"
 |  | ||||||
|                     //             color="primary"
 |  | ||||||
|                     //             onClick={() => { this.props.history.push('/') }}
 |  | ||||||
|                     //         >
 |  | ||||||
|                     //             {Blockly.Msg.button_back}
 |  | ||||||
|                     //         </Button>
 |  | ||||||
|                     // }}
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|  | |||||||
| @ -1,44 +1,41 @@ | |||||||
| import React, { Component } from 'react'; | import React, { Component } from "react"; | ||||||
| import PropTypes from 'prop-types'; | import PropTypes from "prop-types"; | ||||||
| import { connect } from 'react-redux'; | import { connect } from "react-redux"; | ||||||
| 
 |  | ||||||
| import { Route, Redirect, withRouter } from 'react-router-dom'; |  | ||||||
| 
 | 
 | ||||||
|  | import { Route, Redirect, withRouter } from "react-router-dom"; | ||||||
| 
 | 
 | ||||||
| class PrivateRoute extends Component { | class PrivateRoute extends Component { | ||||||
| 
 |  | ||||||
|   render() { |   render() { | ||||||
|     return ( |     return !this.props.progress ? ( | ||||||
|       !this.props.progress ? |  | ||||||
|       <Route |       <Route | ||||||
|         {...this.props.exact} |         {...this.props.exact} | ||||||
|         render={({ location }) => |         render={({ location }) => | ||||||
|           this.props.isAuthenticated ? ( |           this.props.isAuthenticated | ||||||
|             this.props.children |             ? this.props.children | ||||||
|           ) : (()=>{ |             : (() => { | ||||||
|             return ( |                 return ( | ||||||
|               <Redirect |                   <Redirect | ||||||
|                 to={{ |                     to={{ | ||||||
|                   pathname: "/user/login", |                       pathname: "/user/login", | ||||||
|                   state: { from: location } |                       state: { from: location }, | ||||||
|                 }} |                     }} | ||||||
|               /> |                   /> | ||||||
|             ) |                 ); | ||||||
|           })() |               })() | ||||||
|         } |         } | ||||||
|       /> : null |       /> | ||||||
|     ); |     ) : null; | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| PrivateRoute.propTypes = { | PrivateRoute.propTypes = { | ||||||
|   isAuthenticated: PropTypes.bool.isRequired, |   isAuthenticated: PropTypes.bool, | ||||||
|   progress: PropTypes.bool.isRequired |   progress: PropTypes.bool.isRequired, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const mapStateToProps = state => ({ | const mapStateToProps = (state) => ({ | ||||||
|   isAuthenticated: state.auth.isAuthenticated, |   isAuthenticated: state.auth.isAuthenticated, | ||||||
|   progress: state.auth.progress |   progress: state.auth.progress, | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| export default connect(mapStateToProps, null)(withRouter(PrivateRoute)); | export default connect(mapStateToProps, null)(withRouter(PrivateRoute)); | ||||||
|  | |||||||
| @ -74,7 +74,7 @@ class Assessment extends Component { | |||||||
|       (task) => task._id === currentTask._id |       (task) => task._id === currentTask._id | ||||||
|     ); |     ); | ||||||
|     var statusTask = status.tasks[taskIndex]; |     var statusTask = status.tasks[taskIndex]; | ||||||
| 
 |     console.log(statusTask); | ||||||
|     return ( |     return ( | ||||||
|       <div className="assessmentDiv" style={{ width: "100%" }}> |       <div className="assessmentDiv" style={{ width: "100%" }}> | ||||||
|         <div style={{ float: "right", height: "40px" }}> |         <div style={{ float: "right", height: "40px" }}> | ||||||
|  | |||||||
| @ -41,8 +41,6 @@ import FormControl from "@material-ui/core/FormControl"; | |||||||
| import Select from "@material-ui/core/Select"; | import Select from "@material-ui/core/Select"; | ||||||
| import * as Blockly from "blockly"; | import * as Blockly from "blockly"; | ||||||
| 
 | 
 | ||||||
| import MarkdownEditor from "./MarkdownEditor"; |  | ||||||
| 
 |  | ||||||
| const styles = (theme) => ({ | const styles = (theme) => ({ | ||||||
|   backdrop: { |   backdrop: { | ||||||
|     zIndex: theme.zIndex.drawer + 1, |     zIndex: theme.zIndex.drawer + 1, | ||||||
| @ -285,21 +283,6 @@ class Builder extends Component { | |||||||
|           // optional
 |           // optional
 | ||||||
|           newTutorial.append(`steps[${i}][xml]`, step.xml); |           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; |       return newTutorial; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -1,107 +1,159 @@ | |||||||
| import React, { Component } from 'react'; | import React, { Component } from "react"; | ||||||
| import PropTypes from 'prop-types'; | import PropTypes from "prop-types"; | ||||||
| import { connect } from 'react-redux'; | import { connect } from "react-redux"; | ||||||
| import { changeContent, setError, deleteError } from '../../../actions/tutorialBuilderActions'; | import { | ||||||
|  |   changeContent, | ||||||
|  |   setError, | ||||||
|  |   deleteError, | ||||||
|  | } from "../../../actions/tutorialBuilderActions"; | ||||||
| 
 | 
 | ||||||
| import hardware from '../../../data/hardware.json'; | import hardware from "../../../data/hardware.json"; | ||||||
| 
 | 
 | ||||||
| import { withStyles } from '@material-ui/core/styles'; | import { withStyles } from "@material-ui/core/styles"; | ||||||
| import withWidth, { isWidthDown } from '@material-ui/core/withWidth'; | import withWidth, { isWidthDown } from "@material-ui/core/withWidth"; | ||||||
| import GridList from '@material-ui/core/GridList'; | import ImageList from "@material-ui/core/ImageList"; | ||||||
| import GridListTile from '@material-ui/core/GridListTile'; | import ImageListTile from "@material-ui/core/ImageListItem"; | ||||||
| import GridListTileBar from '@material-ui/core/GridListTileBar'; | import ImageListTileBar from "@material-ui/core/ImageListItemBar"; | ||||||
| import FormHelperText from '@material-ui/core/FormHelperText'; | import FormHelperText from "@material-ui/core/FormHelperText"; | ||||||
| import FormLabel from '@material-ui/core/FormLabel'; | import FormLabel from "@material-ui/core/FormLabel"; | ||||||
| import * as Blockly from 'blockly' | import * as Blockly from "blockly"; | ||||||
| 
 | 
 | ||||||
| 
 | const styles = (theme) => ({ | ||||||
| const styles = theme => ({ |   multiImageListTile: { | ||||||
|   multiGridListTile: { |  | ||||||
|     background: theme.palette.primary.main, |     background: theme.palette.primary.main, | ||||||
|     opacity: 0.9, |     opacity: 0.9, | ||||||
|     height: '30px' |     height: "30px", | ||||||
|   }, |   }, | ||||||
|   multiGridListTileTitle: { |   multiImageListTileTitle: { | ||||||
|     color: theme.palette.text.primary |     color: theme.palette.text.primary, | ||||||
|   }, |   }, | ||||||
|   border: { |   border: { | ||||||
|     cursor: 'pointer', |     cursor: "pointer", | ||||||
|     '&:hover': { |     "&:hover": { | ||||||
|       width: 'calc(100% - 4px)', |       width: "calc(100% - 4px)", | ||||||
|       height: 'calc(100% - 4px)', |       height: "calc(100% - 4px)", | ||||||
|       border: `2px solid ${theme.palette.primary.main}` |       border: `2px solid ${theme.palette.primary.main}`, | ||||||
|     } |     }, | ||||||
|   }, |   }, | ||||||
|   active: { |   active: { | ||||||
|     cursor: 'pointer', |     cursor: "pointer", | ||||||
|     width: 'calc(100% - 4px)', |     width: "calc(100% - 4px)", | ||||||
|     height: 'calc(100% - 4px)', |     height: "calc(100% - 4px)", | ||||||
|     border: `2px solid ${theme.palette.primary.main}` |     border: `2px solid ${theme.palette.primary.main}`, | ||||||
|   }, |   }, | ||||||
|   errorColor: { |   errorColor: { | ||||||
|     color: theme.palette.error.dark, |     color: theme.palette.error.dark, | ||||||
|     lineHeight: 'initial', |     lineHeight: "initial", | ||||||
|     marginBottom: '10px' |     marginBottom: "10px", | ||||||
|   } |   }, | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| class Requirements extends Component { | class Requirements extends Component { | ||||||
| 
 |  | ||||||
|   onChange = (hardware) => { |   onChange = (hardware) => { | ||||||
|     var hardwareArray = this.props.value; |     var hardwareArray = this.props.value; | ||||||
|     if (hardwareArray.filter(value => value === hardware).length > 0) { |     if (hardwareArray.filter((value) => value === hardware).length > 0) { | ||||||
|       hardwareArray = hardwareArray.filter(value => value !== hardware); |       hardwareArray = hardwareArray.filter((value) => value !== hardware); | ||||||
|     } |     } else { | ||||||
|     else { |  | ||||||
|       hardwareArray.push(hardware); |       hardwareArray.push(hardware); | ||||||
|       if (this.props.error) { |       if (this.props.error) { | ||||||
|         this.props.deleteError(this.props.index, 'hardware'); |         this.props.deleteError(this.props.index, "hardware"); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     this.props.changeContent(hardwareArray, this.props.index, 'hardware'); |     this.props.changeContent(hardwareArray, this.props.index, "hardware"); | ||||||
|     if (hardwareArray.length === 0) { |     if (hardwareArray.length === 0) { | ||||||
|       this.props.setError(this.props.index, 'hardware'); |       this.props.setError(this.props.index, "hardware"); | ||||||
|     } |     } | ||||||
|   } |   }; | ||||||
| 
 | 
 | ||||||
|   render() { |   render() { | ||||||
|     var cols = isWidthDown('md', this.props.width) ? isWidthDown('sm', this.props.width) ? isWidthDown('xs', this.props.width) ? 2 : 3 : 4 : 6; |     var cols = isWidthDown("md", this.props.width) | ||||||
|  |       ? isWidthDown("sm", this.props.width) | ||||||
|  |         ? isWidthDown("xs", this.props.width) | ||||||
|  |           ? 2 | ||||||
|  |           : 3 | ||||||
|  |         : 4 | ||||||
|  |       : 6; | ||||||
|     return ( |     return ( | ||||||
|       <div style={{ marginBottom: '10px', padding: '18.5px 14px', borderRadius: '25px', border: '1px solid lightgrey', width: 'calc(100% - 28px)' }}> |       <div | ||||||
|         <FormLabel style={{ color: 'black' }}>Hardware</FormLabel> |         style={{ | ||||||
|         <FormHelperText style={this.props.error ? { lineHeight: 'initial', marginTop: '5px' } : { marginTop: '5px', lineHeight: 'initial', marginBottom: '10px' }}>{Blockly.Msg.builder_hardware_order}</FormHelperText> |           marginBottom: "10px", | ||||||
|         {this.props.error ? <FormHelperText className={this.props.classes.errorColor}>{Blockly.Msg.builder_hardware_helper}</FormHelperText> : null} |           padding: "18.5px 14px", | ||||||
|         <GridList cellHeight={100} cols={cols} spacing={10}> |           borderRadius: "25px", | ||||||
|  |           border: "1px solid lightgrey", | ||||||
|  |           width: "calc(100% - 28px)", | ||||||
|  |         }} | ||||||
|  |       > | ||||||
|  |         <FormLabel style={{ color: "black" }}>Hardware</FormLabel> | ||||||
|  |         <FormHelperText | ||||||
|  |           style={ | ||||||
|  |             this.props.error | ||||||
|  |               ? { lineHeight: "initial", marginTop: "5px" } | ||||||
|  |               : { | ||||||
|  |                   marginTop: "5px", | ||||||
|  |                   lineHeight: "initial", | ||||||
|  |                   marginBottom: "10px", | ||||||
|  |                 } | ||||||
|  |           } | ||||||
|  |         > | ||||||
|  |           {Blockly.Msg.builder_hardware_order} | ||||||
|  |         </FormHelperText> | ||||||
|  |         {this.props.error ? ( | ||||||
|  |           <FormHelperText className={this.props.classes.errorColor}> | ||||||
|  |             {Blockly.Msg.builder_hardware_helper} | ||||||
|  |           </FormHelperText> | ||||||
|  |         ) : null} | ||||||
|  |         <ImageList rowHeight={100} cols={cols} gap={10}> | ||||||
|           {hardware.map((picture, i) => ( |           {hardware.map((picture, i) => ( | ||||||
|             <GridListTile key={i} onClick={() => this.onChange(picture.id)} classes={{ tile: this.props.value.filter(value => value === picture.id).length > 0 ? this.props.classes.active : this.props.classes.border }}> |             <ImageListTile | ||||||
|               <div style={{ margin: 'auto', width: 'max-content' }}> |               key={i} | ||||||
|                 <img src={`/media/hardware/${picture.src}`} alt={picture.name} height={100} /> |               onClick={() => this.onChange(picture.id)} | ||||||
|  |               classes={{ | ||||||
|  |                 item: | ||||||
|  |                   this.props.value.filter((value) => value === picture.id) | ||||||
|  |                     .length > 0 | ||||||
|  |                     ? this.props.classes.active | ||||||
|  |                     : this.props.classes.border, | ||||||
|  |               }} | ||||||
|  |             > | ||||||
|  |               <div style={{ margin: "auto", width: "max-content" }}> | ||||||
|  |                 <img | ||||||
|  |                   src={`/media/hardware/${picture.src}`} | ||||||
|  |                   alt={picture.name} | ||||||
|  |                   height={100} | ||||||
|  |                 /> | ||||||
|               </div> |               </div> | ||||||
|               <GridListTileBar |               <ImageListTileBar | ||||||
|                 classes={{ root: this.props.classes.multiGridListTile }} |                 classes={{ root: this.props.classes.multiImageListTile }} | ||||||
|                 title={ |                 title={ | ||||||
|                   <div style={{ overflow: 'hidden', textOverflow: 'ellipsis' }} className={this.props.classes.multiGridListTileTitle}> |                   <div | ||||||
|  |                     style={{ overflow: "hidden", textOverflow: "ellipsis" }} | ||||||
|  |                     className={this.props.classes.multiImageListTileTitle} | ||||||
|  |                   > | ||||||
|                     {picture.name} |                     {picture.name} | ||||||
|                   </div> |                   </div> | ||||||
|                 } |                 } | ||||||
|               /> |               /> | ||||||
|             </GridListTile> |             </ImageListTile> | ||||||
|           ))} |           ))} | ||||||
|         </GridList> |         </ImageList> | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
|   }; |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Requirements.propTypes = { | Requirements.propTypes = { | ||||||
|   changeContent: PropTypes.func.isRequired, |   changeContent: PropTypes.func.isRequired, | ||||||
|   setError: PropTypes.func.isRequired, |   setError: PropTypes.func.isRequired, | ||||||
|   deleteError: PropTypes.func.isRequired, |   deleteError: PropTypes.func.isRequired, | ||||||
|   change: PropTypes.number.isRequired |   change: PropTypes.number.isRequired, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const mapStateToProps = state => ({ | const mapStateToProps = (state) => ({ | ||||||
|   change: state.builder.change |   change: state.builder.change, | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| export default connect(mapStateToProps, { changeContent, setError, deleteError })(withStyles(styles, { withTheme: true })(withWidth()(Requirements))); | export default connect(mapStateToProps, { | ||||||
|  |   changeContent, | ||||||
|  |   setError, | ||||||
|  |   deleteError, | ||||||
|  | })(withStyles(styles, { withTheme: true })(withWidth()(Requirements))); | ||||||
|  | |||||||
| @ -1,16 +1,14 @@ | |||||||
| import React, { Component, useRef } from "react"; | import React from "react"; | ||||||
| import PropTypes from "prop-types"; |  | ||||||
| import { connect } from "react-redux"; | import { connect } from "react-redux"; | ||||||
| import { | import { | ||||||
|     tutorialTitle, |   tutorialTitle, | ||||||
|     jsonString, |   jsonString, | ||||||
|     changeContent, |   changeContent, | ||||||
|     setError, |   setError, | ||||||
|     deleteError, |   deleteError, | ||||||
| } from "../../../actions/tutorialBuilderActions"; | } from "../../../actions/tutorialBuilderActions"; | ||||||
| 
 | 
 | ||||||
| import FormControl from "@material-ui/core/FormControl"; | import FormControl from "@material-ui/core/FormControl"; | ||||||
| import Button from "@material-ui/core/Button"; |  | ||||||
| import MarkdownIt from "markdown-it"; | import MarkdownIt from "markdown-it"; | ||||||
| import Editor from "react-markdown-editor-lite"; | import Editor from "react-markdown-editor-lite"; | ||||||
| import "react-markdown-editor-lite/lib/index.css"; | import "react-markdown-editor-lite/lib/index.css"; | ||||||
| @ -20,63 +18,64 @@ import axios from "axios"; | |||||||
| const mdParser = new MarkdownIt(/* Markdown-it options */); | const mdParser = new MarkdownIt(/* Markdown-it options */); | ||||||
| 
 | 
 | ||||||
| const MarkdownEditor = (props) => { | const MarkdownEditor = (props) => { | ||||||
|     const [value, setValue] = React.useState(props.value); |   //const [value, setValue] = React.useState(props.value);
 | ||||||
| 
 | 
 | ||||||
|     const mdEditor = React.useRef(null); |   const mdEditor = React.useRef(null); | ||||||
| 
 | 
 | ||||||
|     function handleChange({ html, text }) { |   function handleChange({ html, text }) { | ||||||
|         setValue(text); |     //setValue(text);
 | ||||||
|         var value = text; |     var value = text; | ||||||
|         console.log(text); |     props.changeContent(value, props.index, props.property, props.property2); | ||||||
|         props.changeContent(value, props.index, props.property, props.property2); |     if (value.replace(/\s/g, "") === "") { | ||||||
|         if (value.replace(/\s/g, "") === "") { |       props.setError(props.index, props.property); | ||||||
|             props.setError(props.index, props.property); |     } else { | ||||||
|         } else { |       props.deleteError(props.index, props.property); | ||||||
|             props.deleteError(props.index, props.property); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|     async function uploadImage(files) { |   async function uploadImage(files) { | ||||||
|         return new Promise((resolve, reject) => { |     return new Promise((resolve, reject) => { | ||||||
|             const formData = new FormData(); |       const formData = new FormData(); | ||||||
|             formData.append("files", files); |       formData.append("files", files); | ||||||
|             axios({ |       axios({ | ||||||
|                 method: "post", |         method: "post", | ||||||
|                 url: `${process.env.REACT_APP_BLOCKLY_API}/upload/uploadImage`, |         url: `${process.env.REACT_APP_BLOCKLY_API}/upload/uploadImage`, | ||||||
|                 data: formData, |         data: formData, | ||||||
|                 headers: { "Content-Type": "multipart/form-data" }, |         headers: { "Content-Type": "multipart/form-data" }, | ||||||
|             }) |       }) | ||||||
|                 .then((res) => { |         .then((res) => { | ||||||
|                     console.log(res); |           console.log(res); | ||||||
|                     resolve(`${process.env.REACT_APP_BLOCKLY_API}/upload/`+res.data.filename); |           resolve( | ||||||
|                 }) |             `${process.env.REACT_APP_BLOCKLY_API}/upload/` + res.data.filename | ||||||
|                 .catch((err) => { |           ); | ||||||
|                     reject(new Error("error")); |  | ||||||
|                 }) |  | ||||||
|         }) |         }) | ||||||
|     } |         .catch((err) => { | ||||||
|  |           reject(new Error("error")); | ||||||
|  |         }); | ||||||
|  |     }); | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|     return ( |   return ( | ||||||
|         <FormControl variant="outlined" fullWidth style={{ marginBottom: "10px" }}> |     <FormControl variant="outlined" fullWidth style={{ marginBottom: "10px" }}> | ||||||
|             <Editor |       <Editor | ||||||
|                 ref={mdEditor} |         ref={mdEditor} | ||||||
|                 style={{ height: "500px" }} |         style={{ height: "500px" }} | ||||||
|                 renderHTML={(text) => mdParser.render(text)} |         renderHTML={(text) => mdParser.render(text)} | ||||||
|                 onChange={handleChange} |         onChange={handleChange} | ||||||
|                 value={value} |         //value={value}
 | ||||||
|                 id={props.property} |         id={props.property} | ||||||
|                 label={props.label} |         label={props.label} | ||||||
|                 property={props.property} |         property={props.property} | ||||||
|                 onImageUpload={uploadImage} |         onImageUpload={uploadImage} | ||||||
|             /> |       /> | ||||||
|         </FormControl> |     </FormControl> | ||||||
|     ); |   ); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export default connect(null, { | export default connect(null, { | ||||||
|     tutorialTitle, |   tutorialTitle, | ||||||
|     jsonString, |   jsonString, | ||||||
|     changeContent, |   changeContent, | ||||||
|     setError, |   setError, | ||||||
|     deleteError, |   deleteError, | ||||||
| })(MarkdownEditor); | })(MarkdownEditor); | ||||||
| @ -1,23 +1,31 @@ | |||||||
| import React, { Component } from 'react'; | import React, { Component } from "react"; | ||||||
| import PropTypes from 'prop-types'; | import PropTypes from "prop-types"; | ||||||
| import { connect } from 'react-redux'; | import { connect } from "react-redux"; | ||||||
| import { addStep, removeStep, changeStepIndex } from '../../../actions/tutorialBuilderActions'; | import { | ||||||
|  |   addStep, | ||||||
|  |   removeStep, | ||||||
|  |   changeStepIndex, | ||||||
|  | } from "../../../actions/tutorialBuilderActions"; | ||||||
| 
 | 
 | ||||||
| import clsx from 'clsx'; | import clsx from "clsx"; | ||||||
| 
 | 
 | ||||||
| import Textfield from './Textfield'; | import Textfield from "./Textfield"; | ||||||
| import StepType from './StepType'; | import StepType from "./StepType"; | ||||||
| import BlocklyExample from './BlocklyExample'; | import BlocklyExample from "./BlocklyExample"; | ||||||
| import Requirements from './Requirements'; | import Requirements from "./Requirements"; | ||||||
| import Hardware from './Hardware'; | import Hardware from "./Hardware"; | ||||||
| import Media from './Media'; |  | ||||||
| 
 | 
 | ||||||
| import { withStyles } from '@material-ui/core/styles'; | import { withStyles } from "@material-ui/core/styles"; | ||||||
| import Typography from '@material-ui/core/Typography'; | import Typography from "@material-ui/core/Typography"; | ||||||
| import IconButton from '@material-ui/core/IconButton'; | import IconButton from "@material-ui/core/IconButton"; | ||||||
| import Tooltip from '@material-ui/core/Tooltip'; | import Tooltip from "@material-ui/core/Tooltip"; | ||||||
| 
 | 
 | ||||||
| import { faPlus, faAngleDoubleUp, faAngleDoubleDown, faTrash } from "@fortawesome/free-solid-svg-icons"; | import { | ||||||
|  |   faPlus, | ||||||
|  |   faAngleDoubleUp, | ||||||
|  |   faAngleDoubleDown, | ||||||
|  |   faTrash, | ||||||
|  | } from "@fortawesome/free-solid-svg-icons"; | ||||||
| import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||||
| 
 | 
 | ||||||
| import MarkdownEditor from "./MarkdownEditor"; | import MarkdownEditor from "./MarkdownEditor"; | ||||||
| @ -26,59 +34,84 @@ const styles = (theme) => ({ | |||||||
|   button: { |   button: { | ||||||
|     backgroundColor: theme.palette.primary.main, |     backgroundColor: theme.palette.primary.main, | ||||||
|     color: theme.palette.primary.contrastText, |     color: theme.palette.primary.contrastText, | ||||||
|     width: '40px', |     width: "40px", | ||||||
|     height: '40px', |     height: "40px", | ||||||
|     '&:hover': { |     "&:hover": { | ||||||
|       backgroundColor: theme.palette.primary.main, |       backgroundColor: theme.palette.primary.main, | ||||||
|       color: theme.palette.primary.contrastText, |       color: theme.palette.primary.contrastText, | ||||||
|     } |     }, | ||||||
|   }, |   }, | ||||||
|   delete: { |   delete: { | ||||||
|     backgroundColor: theme.palette.error.dark, |     backgroundColor: theme.palette.error.dark, | ||||||
|     color: theme.palette.error.contrastText, |     color: theme.palette.error.contrastText, | ||||||
|     '&:hover': { |     "&:hover": { | ||||||
|       backgroundColor: theme.palette.error.dark, |       backgroundColor: theme.palette.error.dark, | ||||||
|       color: theme.palette.error.contrastText, |       color: theme.palette.error.contrastText, | ||||||
|     } |     }, | ||||||
|   } |   }, | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| class Step extends Component { | class Step extends Component { | ||||||
| 
 |  | ||||||
|   render() { |   render() { | ||||||
|     var index = this.props.index; |     var index = this.props.index; | ||||||
|     var steps = this.props.steps; |     var steps = this.props.steps; | ||||||
|     return ( |     return ( | ||||||
|       <div style={{ borderRadius: '25px', border: '1px solid lightgrey', padding: '10px 14px 10px 10px', marginBottom: '20px' }}> |       <div | ||||||
|         <Typography variant='h6' style={{ marginBottom: '10px', marginLeft: '4px' }}>Schritt {index + 1}</Typography> |         style={{ | ||||||
|         <div style={{ display: 'flex', position: 'relative' }}> |           borderRadius: "25px", | ||||||
|           <div style={{ width: '40px', marginRight: '10px', position: 'absolute', left: '4px', bottom: '10px' }}> |           border: "1px solid lightgrey", | ||||||
|             <Tooltip title='Schritt hinzufügen' arrow> |           padding: "10px 14px 10px 10px", | ||||||
|  |           marginBottom: "20px", | ||||||
|  |         }} | ||||||
|  |       > | ||||||
|  |         <Typography | ||||||
|  |           variant="h6" | ||||||
|  |           style={{ marginBottom: "10px", marginLeft: "4px" }} | ||||||
|  |         > | ||||||
|  |           Schritt {index + 1} | ||||||
|  |         </Typography> | ||||||
|  |         <div style={{ display: "flex", position: "relative" }}> | ||||||
|  |           <div | ||||||
|  |             style={{ | ||||||
|  |               width: "40px", | ||||||
|  |               marginRight: "10px", | ||||||
|  |               position: "absolute", | ||||||
|  |               left: "4px", | ||||||
|  |               bottom: "10px", | ||||||
|  |             }} | ||||||
|  |           > | ||||||
|  |             <Tooltip title="Schritt hinzufügen" arrow> | ||||||
|               <IconButton |               <IconButton | ||||||
|                 className={this.props.classes.button} |                 className={this.props.classes.button} | ||||||
|                 style={index === 0 ? {} : { marginBottom: '5px' }} |                 style={index === 0 ? {} : { marginBottom: "5px" }} | ||||||
|                 onClick={() => this.props.addStep(index + 1)} |                 onClick={() => this.props.addStep(index + 1)} | ||||||
|               > |               > | ||||||
|                 <FontAwesomeIcon icon={faPlus} size="xs" /> |                 <FontAwesomeIcon icon={faPlus} size="xs" /> | ||||||
|               </IconButton> |               </IconButton> | ||||||
|             </Tooltip> |             </Tooltip> | ||||||
|             {index !== 0 ? |             {index !== 0 ? ( | ||||||
|               <div> |               <div> | ||||||
|                 <Tooltip title={`Schritt ${index + 1} nach oben schieben`} arrow> |                 <Tooltip | ||||||
|  |                   title={`Schritt ${index + 1} nach oben schieben`} | ||||||
|  |                   arrow | ||||||
|  |                 > | ||||||
|                   <IconButton |                   <IconButton | ||||||
|                     disabled={index < 2} |                     disabled={index < 2} | ||||||
|                     className={this.props.classes.button} |                     className={this.props.classes.button} | ||||||
|                     style={{ marginBottom: '5px' }} |                     style={{ marginBottom: "5px" }} | ||||||
|                     onClick={() => this.props.changeStepIndex(index, index - 1)} |                     onClick={() => this.props.changeStepIndex(index, index - 1)} | ||||||
|                   > |                   > | ||||||
|                     <FontAwesomeIcon icon={faAngleDoubleUp} size="xs" /> |                     <FontAwesomeIcon icon={faAngleDoubleUp} size="xs" /> | ||||||
|                   </IconButton> |                   </IconButton> | ||||||
|                 </Tooltip> |                 </Tooltip> | ||||||
|                 <Tooltip title={`Schritt ${index + 1} nach unten schieben`} arrow> |                 <Tooltip | ||||||
|  |                   title={`Schritt ${index + 1} nach unten schieben`} | ||||||
|  |                   arrow | ||||||
|  |                 > | ||||||
|                   <IconButton |                   <IconButton | ||||||
|                     disabled={index === steps.length - 1} |                     disabled={index === steps.length - 1} | ||||||
|                     className={this.props.classes.button} |                     className={this.props.classes.button} | ||||||
|                     style={{ marginBottom: '5px' }} |                     style={{ marginBottom: "5px" }} | ||||||
|                     onClick={() => this.props.changeStepIndex(index, index + 1)} |                     onClick={() => this.props.changeStepIndex(index, index + 1)} | ||||||
|                   > |                   > | ||||||
|                     <FontAwesomeIcon icon={faAngleDoubleDown} size="xs" /> |                     <FontAwesomeIcon icon={faAngleDoubleDown} size="xs" /> | ||||||
| @ -87,16 +120,19 @@ class Step extends Component { | |||||||
|                 <Tooltip title={`Schritt ${index + 1} löschen`} arrow> |                 <Tooltip title={`Schritt ${index + 1} löschen`} arrow> | ||||||
|                   <IconButton |                   <IconButton | ||||||
|                     disabled={index === 0} |                     disabled={index === 0} | ||||||
|                     className={clsx(this.props.classes.button, this.props.classes.delete)} |                     className={clsx( | ||||||
|  |                       this.props.classes.button, | ||||||
|  |                       this.props.classes.delete | ||||||
|  |                     )} | ||||||
|                     onClick={() => this.props.removeStep(index)} |                     onClick={() => this.props.removeStep(index)} | ||||||
|                   > |                   > | ||||||
|                     <FontAwesomeIcon icon={faTrash} size="xs" /> |                     <FontAwesomeIcon icon={faTrash} size="xs" /> | ||||||
|                   </IconButton> |                   </IconButton> | ||||||
|                 </Tooltip> |                 </Tooltip> | ||||||
|               </div> |               </div> | ||||||
|               : null} |             ) : null} | ||||||
|           </div> |           </div> | ||||||
|           <div style={{ width: '100%', marginLeft: '54px' }}> |           <div style={{ width: "100%", marginLeft: "54px" }}> | ||||||
|             <StepType value={this.props.step.type} index={index} /> |             <StepType value={this.props.step.type} index={index} /> | ||||||
|             <Textfield |             <Textfield | ||||||
|               value={this.props.step.headline} |               value={this.props.step.headline} | ||||||
| @ -104,8 +140,9 @@ class Step extends Component { | |||||||
|               label={"Überschrift"} |               label={"Überschrift"} | ||||||
|               index={index} |               index={index} | ||||||
|               error={this.props.error.steps[index].headline} |               error={this.props.error.steps[index].headline} | ||||||
|               errorText={`Gib eine Überschrift für die ${this.props.step.type === "task" ? "Aufgabe" : "Anleitung" |               errorText={`Gib eine Überschrift für die ${ | ||||||
|                 } ein.`}
 |                 this.props.step.type === "task" ? "Aufgabe" : "Anleitung" | ||||||
|  |               } ein.`}
 | ||||||
|             /> |             /> | ||||||
|             <MarkdownEditor |             <MarkdownEditor | ||||||
|               value={this.props.step.text} |               value={this.props.step.text} | ||||||
| @ -118,24 +155,40 @@ class Step extends Component { | |||||||
|               index={index} |               index={index} | ||||||
|               multiline |               multiline | ||||||
|               error={this.props.error.steps[index].text} |               error={this.props.error.steps[index].text} | ||||||
|               errorText={`Gib Instruktionen für die ${this.props.step.type === "task" ? "Aufgabe" : "Anleitung" |               errorText={`Gib Instruktionen für die ${ | ||||||
|                 } ein.`}
 |                 this.props.step.type === "task" ? "Aufgabe" : "Anleitung" | ||||||
|  |               } ein.`}
 | ||||||
|             /> |             /> | ||||||
|             {index === 0 ? |             {index === 0 ? ( | ||||||
|               <div> |               <div> | ||||||
|                 <Requirements value={this.props.step.requirements ? this.props.step.requirements : []} index={index} /> |                 <Requirements | ||||||
|                 <Hardware value={this.props.step.hardware ? this.props.step.hardware : []} index={index} error={this.props.error.steps[index].hardware} /> |                   value={ | ||||||
|  |                     this.props.step.requirements | ||||||
|  |                       ? this.props.step.requirements | ||||||
|  |                       : [] | ||||||
|  |                   } | ||||||
|  |                   index={index} | ||||||
|  |                 /> | ||||||
|  |                 <Hardware | ||||||
|  |                   value={ | ||||||
|  |                     this.props.step.hardware ? this.props.step.hardware : [] | ||||||
|  |                   } | ||||||
|  |                   index={index} | ||||||
|  |                   error={this.props.error.steps[index].hardware} | ||||||
|  |                 /> | ||||||
|               </div> |               </div> | ||||||
|               : null} |             ) : null} | ||||||
|             {this.props.step.type === 'instruction' ? |             <BlocklyExample | ||||||
|               <Media value={this.props.step.media} picture={this.props.step.media && this.props.step.media.picture} youtube={this.props.step.media && this.props.step.media.youtube} url={this.props.step.url} index={index} error={this.props.error.steps[index].media} /> |               value={this.props.step.xml} | ||||||
|               : null} |               index={index} | ||||||
|             <BlocklyExample value={this.props.step.xml} index={index} task={this.props.step.type === 'task'} error={this.props.error.steps[index].xml ? true : false} /> |               task={this.props.step.type === "task"} | ||||||
|  |               error={this.props.error.steps[index].xml ? true : false} | ||||||
|  |             /> | ||||||
|           </div> |           </div> | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
|   }; |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Step.propTypes = { | Step.propTypes = { | ||||||
| @ -147,10 +200,14 @@ Step.propTypes = { | |||||||
|   error: PropTypes.object.isRequired, |   error: PropTypes.object.isRequired, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const mapStateToProps = state => ({ | const mapStateToProps = (state) => ({ | ||||||
|   steps: state.builder.steps, |   steps: state.builder.steps, | ||||||
|   change: state.builder.change, |   change: state.builder.change, | ||||||
|   error: state.builder.error |   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)); | ||||||
|  | |||||||
| @ -31,14 +31,6 @@ const styles = (theme) => ({ | |||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| class Textfield extends Component { | class Textfield extends Component { | ||||||
|   componentDidMount() { |  | ||||||
|     if (this.props.error) { |  | ||||||
|       if (this.props.property !== "media") { |  | ||||||
|         this.props.deleteError(this.props.index, this.props.property); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   handleChange = (e) => { |   handleChange = (e) => { | ||||||
|     var value = e.target.value; |     var value = e.target.value; | ||||||
|     if (this.props.property === "title") { |     if (this.props.property === "title") { | ||||||
|  | |||||||
| @ -1,47 +1,45 @@ | |||||||
| import React, { Component } from 'react'; | import React, { Component } from "react"; | ||||||
| 
 | 
 | ||||||
| import Dialog from '../Dialog'; | import Dialog from "../Dialog"; | ||||||
| 
 | 
 | ||||||
| import hardware from '../../data/hardware.json'; | import hardware from "../../data/hardware.json"; | ||||||
| 
 | 
 | ||||||
| import { withStyles } from '@material-ui/core/styles'; | import { withStyles } from "@material-ui/core/styles"; | ||||||
| import withWidth, { isWidthDown } from '@material-ui/core/withWidth'; | import withWidth, { isWidthDown } from "@material-ui/core/withWidth"; | ||||||
| import Link from '@material-ui/core/Link'; | import Link from "@material-ui/core/Link"; | ||||||
| import Typography from '@material-ui/core/Typography'; | import Typography from "@material-ui/core/Typography"; | ||||||
| import IconButton from '@material-ui/core/IconButton'; | import IconButton from "@material-ui/core/IconButton"; | ||||||
| import GridList from '@material-ui/core/GridList'; | import ImageList from "@material-ui/core/ImageList"; | ||||||
| import GridListTile from '@material-ui/core/GridListTile'; | import ImageListTile from "@material-ui/core/ImageList"; | ||||||
| import GridListTileBar from '@material-ui/core/GridListTileBar'; | import ImageListTileBar from "@material-ui/core/ImageListItemBar"; | ||||||
| 
 | 
 | ||||||
| import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||||
| import { faExpandAlt } from "@fortawesome/free-solid-svg-icons"; | import { faExpandAlt } from "@fortawesome/free-solid-svg-icons"; | ||||||
| import * as Blockly from 'blockly' | import * as Blockly from "blockly"; | ||||||
| const styles = theme => ({ | const styles = (theme) => ({ | ||||||
|   expand: { |   expand: { | ||||||
|     '&:hover': { |     "&:hover": { | ||||||
|       color: theme.palette.primary.main, |       color: theme.palette.primary.main, | ||||||
|     }, |     }, | ||||||
|     '&:active': { |     "&:active": { | ||||||
|       color: theme.palette.primary.main, |       color: theme.palette.primary.main, | ||||||
|     }, |     }, | ||||||
|     color: theme.palette.text.primary |     color: theme.palette.text.primary, | ||||||
|   }, |   }, | ||||||
|   multiGridListTile: { |   multiImageListTile: { | ||||||
|     background: theme.palette.primary.main, |     background: theme.palette.primary.main, | ||||||
|     opacity: 0.9, |     opacity: 0.9, | ||||||
|     height: '30px' |     height: "30px", | ||||||
|  |   }, | ||||||
|  |   multiImageListTileTitle: { | ||||||
|  |     color: theme.palette.text.primary, | ||||||
|   }, |   }, | ||||||
|   multiGridListTileTitle: { |  | ||||||
|     color: theme.palette.text.primary |  | ||||||
|   } |  | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| class Hardware extends Component { | class Hardware extends Component { | ||||||
| 
 |  | ||||||
|   state = { |   state = { | ||||||
|     open: false, |     open: false, | ||||||
|     hardwareInfo: {} |     hardwareInfo: {}, | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   handleClickOpen = (hardwareInfo) => { |   handleClickOpen = (hardwareInfo) => { | ||||||
| @ -53,36 +51,57 @@ class Hardware extends Component { | |||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   render() { |   render() { | ||||||
|     var cols = isWidthDown('md', this.props.width) ? isWidthDown('sm', this.props.width) ? isWidthDown('xs', this.props.width) ? 2 : 3 : 4 : 6; |     var cols = isWidthDown("md", this.props.width) | ||||||
|  |       ? isWidthDown("sm", this.props.width) | ||||||
|  |         ? isWidthDown("xs", this.props.width) | ||||||
|  |           ? 2 | ||||||
|  |           : 3 | ||||||
|  |         : 4 | ||||||
|  |       : 6; | ||||||
|     return ( |     return ( | ||||||
|       <div style={{ marginTop: '10px', marginBottom: '5px' }}> |       <div style={{ marginTop: "10px", marginBottom: "5px" }}> | ||||||
|         <Typography>{Blockly.Msg.tutorials_hardware_head}</Typography> |         <Typography>{Blockly.Msg.tutorials_hardware_head}</Typography> | ||||||
| 
 | 
 | ||||||
|         <GridList cellHeight={100} cols={cols} spacing={10}> |         <ImageList rowHeight={100} cols={cols} spacing={10}> | ||||||
|           {this.props.picture.map((picture, i) => { |           {this.props.picture.map((picture, i) => { | ||||||
|             var hardwareInfo = hardware.filter(hardware => hardware.id === picture)[0]; |             var hardwareInfo = hardware.filter( | ||||||
|  |               (hardware) => hardware.id === picture | ||||||
|  |             )[0]; | ||||||
|             return ( |             return ( | ||||||
|               <GridListTile key={i}> |               <ImageListTile key={i}> | ||||||
|                 <div style={{ margin: 'auto', width: 'max-content' }}> |                 <div style={{ margin: "auto", width: "max-content" }}> | ||||||
|                   <img src={`/media/hardware/${hardwareInfo.src}`} alt={hardwareInfo.name} height={100} style={{ cursor: 'pointer' }} onClick={() => this.handleClickOpen(hardwareInfo)} /> |                   <img | ||||||
|  |                     src={`/media/hardware/${hardwareInfo.src}`} | ||||||
|  |                     alt={hardwareInfo.name} | ||||||
|  |                     height={100} | ||||||
|  |                     style={{ cursor: "pointer" }} | ||||||
|  |                     onClick={() => this.handleClickOpen(hardwareInfo)} | ||||||
|  |                   /> | ||||||
|                 </div> |                 </div> | ||||||
|                 <GridListTileBar |                 <ImageListTileBar | ||||||
|                   classes={{ root: this.props.classes.multiGridListTile }} |                   classes={{ root: this.props.classes.multiImageListTile }} | ||||||
|                   title={ |                   title={ | ||||||
|                     <div style={{ overflow: 'hidden', textOverflow: 'ellipsis' }} className={this.props.classes.multiGridListTileTitle}> |                     <div | ||||||
|  |                       style={{ overflow: "hidden", textOverflow: "ellipsis" }} | ||||||
|  |                       className={this.props.classes.multiImageListTileTitle} | ||||||
|  |                     > | ||||||
|                       {hardwareInfo.name} |                       {hardwareInfo.name} | ||||||
|                     </div> |                     </div> | ||||||
|                   } |                   } | ||||||
|                   actionIcon={ |                   actionIcon={ | ||||||
|                     <IconButton className={this.props.classes.expand} aria-label='Vollbild' onClick={() => this.handleClickOpen(hardwareInfo)}> |                     <IconButton | ||||||
|  |                       className={this.props.classes.expand} | ||||||
|  |                       aria-label="Vollbild" | ||||||
|  |                       onClick={() => this.handleClickOpen(hardwareInfo)} | ||||||
|  |                     > | ||||||
|                       <FontAwesomeIcon icon={faExpandAlt} size="xs" /> |                       <FontAwesomeIcon icon={faExpandAlt} size="xs" /> | ||||||
|                     </IconButton> |                     </IconButton> | ||||||
|                   } |                   } | ||||||
|                 /> |                 /> | ||||||
|               </GridListTile> |               </ImageListTile> | ||||||
|             ) |             ); | ||||||
|           })} |           })} | ||||||
|         </GridList> |         </ImageList> | ||||||
| 
 | 
 | ||||||
|         <Dialog |         <Dialog | ||||||
|           style={{ zIndex: 1500 }} |           style={{ zIndex: 1500 }} | ||||||
| @ -94,14 +113,26 @@ class Hardware extends Component { | |||||||
|           button={Blockly.Msg.button_close} |           button={Blockly.Msg.button_close} | ||||||
|         > |         > | ||||||
|           <div> |           <div> | ||||||
|             <img src={`/media/hardware/${this.state.hardwareInfo.src}`} width="100%" alt={this.state.hardwareInfo.name} /> |             <img | ||||||
|             {Blockly.Msg.tutorials_hardware_moreInformation} <Link rel="noreferrer" target="_blank" href={this.state.hardwareInfo.url} color="primary">{Blockly.Msg.tutorials_hardware_here}</Link>. |               src={`/media/hardware/${this.state.hardwareInfo.src}`} | ||||||
|  |               width="100%" | ||||||
|  |               alt={this.state.hardwareInfo.name} | ||||||
|  |             /> | ||||||
|  |             {Blockly.Msg.tutorials_hardware_moreInformation}{" "} | ||||||
|  |             <Link | ||||||
|  |               rel="noreferrer" | ||||||
|  |               target="_blank" | ||||||
|  |               href={this.state.hardwareInfo.url} | ||||||
|  |               color="primary" | ||||||
|  |             > | ||||||
|  |               {Blockly.Msg.tutorials_hardware_here} | ||||||
|  |             </Link> | ||||||
|  |             . | ||||||
|           </div> |           </div> | ||||||
|         </Dialog> |         </Dialog> | ||||||
| 
 |  | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
|   }; |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export default withWidth()(withStyles(styles, { withTheme: true })(Hardware)); | export default withWidth()(withStyles(styles, { withTheme: true })(Hardware)); | ||||||
|  | |||||||
| @ -235,7 +235,7 @@ WorkspaceName.propTypes = { | |||||||
|   workspaceName: PropTypes.func.isRequired, |   workspaceName: PropTypes.func.isRequired, | ||||||
|   setDescription: PropTypes.func.isRequired, |   setDescription: PropTypes.func.isRequired, | ||||||
|   updateProject: PropTypes.func.isRequired, |   updateProject: PropTypes.func.isRequired, | ||||||
|   name: PropTypes.string.isRequired, |   name: PropTypes.string, | ||||||
|   description: PropTypes.string.isRequired, |   description: PropTypes.string.isRequired, | ||||||
|   message: PropTypes.object.isRequired, |   message: PropTypes.object.isRequired, | ||||||
| }; | }; | ||||||
|  | |||||||
							
								
								
									
										18
									
								
								src/index.js
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								src/index.js
									
									
									
									
									
								
							| @ -1,30 +1,26 @@ | |||||||
| import React from 'react'; | import React from "react"; | ||||||
| import ReactDOM from 'react-dom'; | import ReactDOM from "react-dom"; | ||||||
| import './index.css'; | import "./index.css"; | ||||||
| import App from './App'; | import App from "./App"; | ||||||
| import * as serviceWorker from './serviceWorker'; | import * as serviceWorker from "./serviceWorker"; | ||||||
| import * as Sentry from "@sentry/react"; | import * as Sentry from "@sentry/react"; | ||||||
| import { Integrations } from "@sentry/tracing"; | import { Integrations } from "@sentry/tracing"; | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| Sentry.init({ | Sentry.init({ | ||||||
|   dsn: "https://ffe5d54461f64c46b4bed5d77c130d6f@o507523.ingest.sentry.io/5598758", |   dsn: "https://ffe5d54461f64c46b4bed5d77c130d6f@o507523.ingest.sentry.io/5598758", | ||||||
|   autoSessionTracking: true, |   autoSessionTracking: true, | ||||||
|   integrations: [ |   integrations: [new Integrations.BrowserTracing()], | ||||||
|     new Integrations.BrowserTracing(), |  | ||||||
|   ], |  | ||||||
| 
 | 
 | ||||||
|   // We recommend adjusting this value in production, or using tracesSampler
 |   // We recommend adjusting this value in production, or using tracesSampler
 | ||||||
|   // for finer control
 |   // for finer control
 | ||||||
|   tracesSampleRate: 1.0, |   tracesSampleRate: 1.0, | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| ReactDOM.render( | ReactDOM.render( | ||||||
|   <React.StrictMode> |   <React.StrictMode> | ||||||
|     <App /> |     <App /> | ||||||
|   </React.StrictMode>, |   </React.StrictMode>, | ||||||
|   document.getElementById('root') |   document.getElementById("root") | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| // If you want your app to work offline and load faster, you can change
 | // If you want your app to work offline and load faster, you can change
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user