From a1dad8205bef2523a240c2d4a94d1407b32d8621 Mon Sep 17 00:00:00 2001 From: Mario Pesch Date: Tue, 21 Dec 2021 12:13:31 +0100 Subject: [PATCH] change tutorial and assessment view --- src/components/CodeViewer.js | 142 +++++++++------ src/components/Tutorial/Assessment.js | 138 +++++++++++---- src/components/Tutorial/Instruction.js | 4 +- src/components/Tutorial/StepperHorizontal.js | 172 +++++++++++++------ 4 files changed, 320 insertions(+), 136 deletions(-) diff --git a/src/components/CodeViewer.js b/src/components/CodeViewer.js index 856272c..9586ef8 100644 --- a/src/components/CodeViewer.js +++ b/src/components/CodeViewer.js @@ -1,30 +1,29 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import { connect } from 'react-redux'; +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import { connect } from "react-redux"; import Prism from "prismjs"; import "prismjs/themes/prism.css"; import "prismjs/plugins/line-numbers/prism-line-numbers"; import "prismjs/plugins/line-numbers/prism-line-numbers.css"; -import withWidth from '@material-ui/core/withWidth'; -import { withStyles } from '@material-ui/core/styles'; -import MuiAccordion from '@material-ui/core/Accordion'; -import MuiAccordionSummary from '@material-ui/core/AccordionSummary'; -import MuiAccordionDetails from '@material-ui/core/AccordionDetails'; -import { Card } from '@material-ui/core'; -import * as Blockly from 'blockly' - +import withWidth from "@material-ui/core/withWidth"; +import { withStyles } from "@material-ui/core/styles"; +import MuiAccordion from "@material-ui/core/Accordion"; +import MuiAccordionSummary from "@material-ui/core/AccordionSummary"; +import MuiAccordionDetails from "@material-ui/core/AccordionDetails"; +import { Card } from "@material-ui/core"; +import * as Blockly from "blockly"; const Accordion = withStyles((theme) => ({ root: { border: `1px solid ${theme.palette.secondary.main}`, - boxShadow: 'none', - '&:before': { - display: 'none', + boxShadow: "none", + "&:before": { + display: "none", }, - '&$expanded': { - margin: 'auto', + "&$expanded": { + margin: "auto", }, }, expanded: {}, @@ -34,15 +33,15 @@ const AccordionSummary = withStyles((theme) => ({ root: { backgroundColor: theme.palette.secondary.main, borderBottom: `1px solid white`, - marginBottom: '-1px', - minHeight: '50px', - '&$expanded': { - minHeight: '50px', + marginBottom: "-1px", + minHeight: "50px", + "&$expanded": { + minHeight: "50px", }, }, content: { - '&$expanded': { - margin: '12px 0', + "&$expanded": { + margin: "12px 0", }, }, expanded: {}, @@ -54,40 +53,37 @@ const AccordionDetails = withStyles((theme) => ({ }, }))(MuiAccordionDetails); - class CodeViewer extends Component { - constructor(props) { super(props); this.state = { expanded: true, - componentHeight: null + componentHeight: null, }; this.myDiv = React.createRef(); } componentDidMount() { Prism.highlightAll(); - this.setState({ componentHeight: this.myDiv.current.offsetHeight + 'px' }); + this.setState({ componentHeight: this.myDiv.current.offsetHeight + "px" }); } componentDidUpdate(props, state) { - if (this.myDiv.current && this.myDiv.current.offsetHeight + 'px' !== this.state.componentHeight) { - this.setState({ componentHeight: this.myDiv.current.offsetHeight + 'px' }); - } + // if (this.myDiv.current && this.myDiv.current.offsetHeight + 'px' !== this.state.componentHeight) { + // this.setState({ componentHeight: this.myDiv.current.offsetHeight + 'px' }); + // } Prism.highlightAll(); } onChange = () => { this.setState({ expanded: !this.state.expanded }); - - } + }; render() { - var curlyBrackets = '{ }'; - var unequal = '<>'; + var curlyBrackets = "{ }"; + var unequal = "<>"; return ( - + - {curlyBrackets} -
{Blockly.Msg.codeviewer_arduino}
+ + {curlyBrackets} + +
+ {Blockly.Msg.codeviewer_arduino} +
- -
-              
-                {this.props.arduino}
-              
+          
+            
+              {this.props.arduino}
             
@@ -113,32 +130,53 @@ class CodeViewer extends Component { onChange={this.onChange} > - {unequal} -
{Blockly.Msg.codeviewer_xml}
+ + {unequal} + +
+ {Blockly.Msg.codeviewer_xml} +
- -
-              
-                {`${this.props.xml}`}
-              
+          
+            
+              {`${this.props.xml}`}
             
); - }; + } } CodeViewer.propTypes = { arduino: PropTypes.string.isRequired, xml: PropTypes.string.isRequired, - tooltip: PropTypes.string.isRequired + tooltip: PropTypes.string.isRequired, }; -const mapStateToProps = state => ({ +const mapStateToProps = (state) => ({ arduino: state.workspace.code.arduino, xml: state.workspace.code.xml, - tooltip: state.workspace.code.tooltip + tooltip: state.workspace.code.tooltip, }); export default connect(mapStateToProps, null)(withWidth()(CodeViewer)); diff --git a/src/components/Tutorial/Assessment.js b/src/components/Tutorial/Assessment.js index 5dd24b7..d69821f 100644 --- a/src/components/Tutorial/Assessment.js +++ b/src/components/Tutorial/Assessment.js @@ -4,7 +4,6 @@ import { connect } from "react-redux"; import { workspaceName } from "../../actions/workspaceActions"; import BlocklyWindow from "../Blockly/BlocklyWindow"; -import CodeViewer from "../CodeViewer"; import WorkspaceFunc from "../Workspace/WorkspaceFunc"; import withWidth, { isWidthDown } from "@material-ui/core/withWidth"; @@ -13,8 +12,44 @@ import Card from "@material-ui/core/Card"; import Typography from "@material-ui/core/Typography"; import * as Blockly from "blockly"; import { initialXml } from "../Blockly/initialXml"; +import IconButton from "@material-ui/core/IconButton"; +import CodeViewer from "../CodeViewer"; +import TooltipViewer from "../TooltipViewer"; +import Tooltip from "@material-ui/core/Tooltip"; +import ReactMarkdown from "react-markdown"; +import { faCode } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { withStyles } from "@material-ui/core/styles"; + +const styles = (theme) => ({ + codeOn: { + backgroundColor: theme.palette.primary.main, + color: theme.palette.primary.contrastText, + "&:hover": { + backgroundColor: theme.palette.primary.contrastText, + color: theme.palette.primary.main, + border: `1px solid ${theme.palette.secondary.main}`, + }, + }, + codeOff: { + backgroundColor: theme.palette.primary.contrastText, + color: theme.palette.primary.main, + border: `1px solid ${theme.palette.secondary.main}`, + "&:hover": { + backgroundColor: theme.palette.primary.main, + color: theme.palette.primary.contrastText, + }, + }, +}); class Assessment extends Component { + constructor(props) { + super(props); + this.state = { + codeOn: false, + }; + } + componentDidMount() { this.props.workspaceName(this.props.name); } @@ -25,6 +60,10 @@ class Assessment extends Component { } } + onChange = () => { + this.setState({ codeOn: !this.state.codeOn }); + }; + render() { var tutorialId = this.props.tutorial._id; var currentTask = this.props.step; @@ -38,50 +77,41 @@ class Assessment extends Component { return (
- - {currentTask.headline} -
- - - - - {Blockly.Msg.tutorials_assessment_task} + + {currentTask.text} - {currentTask.text} + + +
- -
+ >
+ + + this.onChange()} + > + + + + + + {this.state.codeOn ? ( + + + + ) : null} ); @@ -113,5 +185,5 @@ const mapStateToProps = (state) => ({ }); export default connect(mapStateToProps, { workspaceName })( - withWidth()(Assessment) + withWidth()(withStyles(styles, { withTheme: true })(Assessment)) ); diff --git a/src/components/Tutorial/Instruction.js b/src/components/Tutorial/Instruction.js index fc72447..0c3ec21 100644 --- a/src/components/Tutorial/Instruction.js +++ b/src/components/Tutorial/Instruction.js @@ -15,9 +15,9 @@ class Instruction extends Component { var areRequirements = step.requirements && step.requirements.length > 0; return (
- + {/* {step.headline} - + */} ({ stepper: { - width: 'calc(100% - 40px)', - height: '40px', - borderRadius: '25px', - padding: '0 20px', - margin: '20px 0', - display: 'flex', - justifyContent: 'space-between' + width: "calc(100% - 40px)", + height: "40px", + borderRadius: "25px", + padding: "0 20px", + margin: "20px 0", + display: "flex", + justifyContent: "space-between", }, stepperSuccess: { backgroundColor: fade(theme.palette.primary.main, 0.6), @@ -37,73 +37,147 @@ const styles = (theme) => ({ backgroundColor: fade(theme.palette.secondary.main, 0.6), }, color: { - backgroundColor: 'transparent ' + backgroundColor: "transparent ", }, iconDivSuccess: { - color: theme.palette.primary.main + color: theme.palette.primary.main, }, iconDivError: { - color: theme.palette.error.dark - } + color: theme.palette.error.dark, + }, }); class StepperHorizontal extends Component { - render() { var tutorialId = this.props.tutorial._id; - var status = this.props.status.filter(status => status._id === tutorialId)[0]; + var status = this.props.status.filter( + (status) => status._id === tutorialId + )[0]; var tasks = status.tasks; - var error = tasks.filter(task => task.type === 'error').length > 0; - var success = tasks.filter(task => task.type === 'success').length / tasks.length; - var tutorialStatus = success === 1 ? 'Success' : error ? 'Error' : 'Other'; + var error = tasks.filter((task) => task.type === "error").length > 0; + var success = + tasks.filter((task) => task.type === "success").length / tasks.length; + var tutorialStatus = success === 1 ? "Success" : error ? "Error" : "Other"; var title = this.props.tutorial.title; + var activeStep = this.props.activeStep; return ( -
- {error || success > 0 ? -
-
- : null} - {success < 1 && !error ? -
-
- : null} +
+ {error || success > 0 ? ( +
+ ) : null} + {success < 1 && !error ? ( +
+ ) : null}
- +
- {tutorialStatus !== 'Other' ?
: null} - {title} + {tutorialStatus !== "Other" ? ( +
+ +
+ ) : null} + + {title} + {title !== this.props.tutorial.steps[activeStep].headline + ? ` - ${this.props.tutorial.steps[activeStep].headline}` + : null} +
); - }; + } } StepperHorizontal.propTypes = { status: PropTypes.array.isRequired, change: PropTypes.number.isRequired, currentTutorialIndex: PropTypes.number.isRequired, - tutorial: PropTypes.object.isRequired + tutorial: PropTypes.object.isRequired, + activeStep: PropTypes.number.isRequired, }; -const mapStateToProps = state => ({ +const mapStateToProps = (state) => ({ change: state.tutorial.change, status: state.tutorial.status, currentTutorialIndex: state.tutorial.currentIndex, - tutorial: state.tutorial.tutorials[0] + activeStep: state.tutorial.activeStep, + tutorial: state.tutorial.tutorials[0], }); -export default connect(mapStateToProps, null)(withRouter(withStyles(styles, { withTheme: true })(StepperHorizontal))); +export default connect( + mapStateToProps, + null +)(withRouter(withStyles(styles, { withTheme: true })(StepperHorizontal)));