change tutorial and assessment view
This commit is contained in:
		
							parent
							
								
									85dc4d7fc9
								
							
						
					
					
						commit
						a1dad8205b
					
				| @ -1,30 +1,29 @@ | |||||||
| 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 Prism from "prismjs"; | import Prism from "prismjs"; | ||||||
| import "prismjs/themes/prism.css"; | import "prismjs/themes/prism.css"; | ||||||
| import "prismjs/plugins/line-numbers/prism-line-numbers"; | import "prismjs/plugins/line-numbers/prism-line-numbers"; | ||||||
| import "prismjs/plugins/line-numbers/prism-line-numbers.css"; | import "prismjs/plugins/line-numbers/prism-line-numbers.css"; | ||||||
| 
 | 
 | ||||||
| import withWidth from '@material-ui/core/withWidth'; | import withWidth from "@material-ui/core/withWidth"; | ||||||
| import { withStyles } from '@material-ui/core/styles'; | import { withStyles } from "@material-ui/core/styles"; | ||||||
| import MuiAccordion from '@material-ui/core/Accordion'; | import MuiAccordion from "@material-ui/core/Accordion"; | ||||||
| import MuiAccordionSummary from '@material-ui/core/AccordionSummary'; | import MuiAccordionSummary from "@material-ui/core/AccordionSummary"; | ||||||
| import MuiAccordionDetails from '@material-ui/core/AccordionDetails'; | import MuiAccordionDetails from "@material-ui/core/AccordionDetails"; | ||||||
| import { Card } from '@material-ui/core'; | import { Card } from "@material-ui/core"; | ||||||
| import * as Blockly from 'blockly' | import * as Blockly from "blockly"; | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| const Accordion = withStyles((theme) => ({ | const Accordion = withStyles((theme) => ({ | ||||||
|   root: { |   root: { | ||||||
|     border: `1px solid ${theme.palette.secondary.main}`, |     border: `1px solid ${theme.palette.secondary.main}`, | ||||||
|     boxShadow: 'none', |     boxShadow: "none", | ||||||
|     '&:before': { |     "&:before": { | ||||||
|       display: 'none', |       display: "none", | ||||||
|     }, |     }, | ||||||
|     '&$expanded': { |     "&$expanded": { | ||||||
|       margin: 'auto', |       margin: "auto", | ||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|   expanded: {}, |   expanded: {}, | ||||||
| @ -34,15 +33,15 @@ const AccordionSummary = withStyles((theme) => ({ | |||||||
|   root: { |   root: { | ||||||
|     backgroundColor: theme.palette.secondary.main, |     backgroundColor: theme.palette.secondary.main, | ||||||
|     borderBottom: `1px solid white`, |     borderBottom: `1px solid white`, | ||||||
|     marginBottom: '-1px', |     marginBottom: "-1px", | ||||||
|     minHeight: '50px', |     minHeight: "50px", | ||||||
|     '&$expanded': { |     "&$expanded": { | ||||||
|       minHeight: '50px', |       minHeight: "50px", | ||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|   content: { |   content: { | ||||||
|     '&$expanded': { |     "&$expanded": { | ||||||
|       margin: '12px 0', |       margin: "12px 0", | ||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|   expanded: {}, |   expanded: {}, | ||||||
| @ -54,40 +53,37 @@ const AccordionDetails = withStyles((theme) => ({ | |||||||
|   }, |   }, | ||||||
| }))(MuiAccordionDetails); | }))(MuiAccordionDetails); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| class CodeViewer extends Component { | class CodeViewer extends Component { | ||||||
| 
 |  | ||||||
|   constructor(props) { |   constructor(props) { | ||||||
|     super(props); |     super(props); | ||||||
|     this.state = { |     this.state = { | ||||||
|       expanded: true, |       expanded: true, | ||||||
|       componentHeight: null |       componentHeight: null, | ||||||
|     }; |     }; | ||||||
|     this.myDiv = React.createRef(); |     this.myDiv = React.createRef(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   componentDidMount() { |   componentDidMount() { | ||||||
|     Prism.highlightAll(); |     Prism.highlightAll(); | ||||||
|     this.setState({ componentHeight: this.myDiv.current.offsetHeight + 'px' }); |     this.setState({ componentHeight: this.myDiv.current.offsetHeight + "px" }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   componentDidUpdate(props, state) { |   componentDidUpdate(props, state) { | ||||||
|     if (this.myDiv.current && this.myDiv.current.offsetHeight + 'px' !== this.state.componentHeight) { |     // if (this.myDiv.current && this.myDiv.current.offsetHeight + 'px' !== this.state.componentHeight) {
 | ||||||
|       this.setState({ componentHeight: this.myDiv.current.offsetHeight + 'px' }); |     //   this.setState({ componentHeight: this.myDiv.current.offsetHeight + 'px' });
 | ||||||
|     } |     // }
 | ||||||
|     Prism.highlightAll(); |     Prism.highlightAll(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   onChange = () => { |   onChange = () => { | ||||||
|     this.setState({ expanded: !this.state.expanded }); |     this.setState({ expanded: !this.state.expanded }); | ||||||
| 
 |   }; | ||||||
|   } |  | ||||||
| 
 | 
 | ||||||
|   render() { |   render() { | ||||||
|     var curlyBrackets = '{ }'; |     var curlyBrackets = "{ }"; | ||||||
|     var unequal = '<>'; |     var unequal = "<>"; | ||||||
|     return ( |     return ( | ||||||
|       <Card style={{ height: '100%', maxHeight: '60vH' }} ref={this.myDiv}> |       <Card style={{ height: "100%", maxHeight: "60vH" }} ref={this.myDiv}> | ||||||
|         <Accordion |         <Accordion | ||||||
|           square={true} |           square={true} | ||||||
|           style={{ margin: 0 }} |           style={{ margin: 0 }} | ||||||
| @ -95,14 +91,35 @@ class CodeViewer extends Component { | |||||||
|           onChange={this.onChange} |           onChange={this.onChange} | ||||||
|         > |         > | ||||||
|           <AccordionSummary> |           <AccordionSummary> | ||||||
|             <b style={{ fontSize: '20px', marginRight: '5px', width: '35px' }}>{curlyBrackets}</b> |             <b style={{ fontSize: "20px", marginRight: "5px", width: "35px" }}> | ||||||
|             <div style={{ margin: 'auto 5px 2px 0px' }}>{Blockly.Msg.codeviewer_arduino}</div> |               {curlyBrackets} | ||||||
|  |             </b> | ||||||
|  |             <div style={{ margin: "auto 5px 2px 0px" }}> | ||||||
|  |               {Blockly.Msg.codeviewer_arduino} | ||||||
|  |             </div> | ||||||
|           </AccordionSummary> |           </AccordionSummary> | ||||||
|           <AccordionDetails style={{ padding: 0, height: `calc(${this.state.componentHeight} - 50px - 50px)`, backgroundColor: 'white' }}> |           <AccordionDetails | ||||||
|             <pre className="line-numbers" style={{ paddingBottom: 0, width: '100%', overflow: 'auto', scrollbarWidth: 'thin', height: 'calc(100% - 30px)', margin: '15px 0', paddingTop: 0, whiteSpace: 'pre-wrap', backgroundColor: 'white' }}> |             style={{ | ||||||
|               <code className="language-clike"> |               padding: 0, | ||||||
|                 {this.props.arduino} |               height: `calc(${this.state.componentHeight} - 50px - 50px)`, | ||||||
|               </code> |               backgroundColor: "white", | ||||||
|  |             }} | ||||||
|  |           > | ||||||
|  |             <pre | ||||||
|  |               className="line-numbers" | ||||||
|  |               style={{ | ||||||
|  |                 paddingBottom: 0, | ||||||
|  |                 width: "100%", | ||||||
|  |                 overflow: "auto", | ||||||
|  |                 scrollbarWidth: "thin", | ||||||
|  |                 height: "calc(100% - 30px)", | ||||||
|  |                 margin: "15px 0", | ||||||
|  |                 paddingTop: 0, | ||||||
|  |                 whiteSpace: "pre-wrap", | ||||||
|  |                 backgroundColor: "white", | ||||||
|  |               }} | ||||||
|  |             > | ||||||
|  |               <code className="language-clike">{this.props.arduino}</code> | ||||||
|             </pre> |             </pre> | ||||||
|           </AccordionDetails> |           </AccordionDetails> | ||||||
|         </Accordion> |         </Accordion> | ||||||
| @ -113,32 +130,53 @@ class CodeViewer extends Component { | |||||||
|           onChange={this.onChange} |           onChange={this.onChange} | ||||||
|         > |         > | ||||||
|           <AccordionSummary> |           <AccordionSummary> | ||||||
|             <b style={{ fontSize: '20px', marginRight: '5px', width: '35px' }}>{unequal}</b> |             <b style={{ fontSize: "20px", marginRight: "5px", width: "35px" }}> | ||||||
|             <div style={{ margin: 'auto 5px 2px 0px' }}>{Blockly.Msg.codeviewer_xml}</div> |               {unequal} | ||||||
|  |             </b> | ||||||
|  |             <div style={{ margin: "auto 5px 2px 0px" }}> | ||||||
|  |               {Blockly.Msg.codeviewer_xml} | ||||||
|  |             </div> | ||||||
|           </AccordionSummary> |           </AccordionSummary> | ||||||
|           <AccordionDetails style={{ padding: 0, height: `calc(${this.state.componentHeight} - 50px - 50px)`, backgroundColor: 'white' }}> |           <AccordionDetails | ||||||
|             <pre className="line-numbers" style={{ paddingBottom: 0, width: '100%', overflow: 'auto', scrollbarWidth: 'thin', height: 'calc(100% - 30px)', margin: '15px 0', paddingTop: 0, whiteSpace: 'pre-wrap', backgroundColor: 'white' }}> |             style={{ | ||||||
|               <code className="language-xml"> |               padding: 0, | ||||||
|                 {`${this.props.xml}`} |               height: `calc(${this.state.componentHeight} - 50px - 50px)`, | ||||||
|               </code> |               backgroundColor: "white", | ||||||
|  |             }} | ||||||
|  |           > | ||||||
|  |             <pre | ||||||
|  |               className="line-numbers" | ||||||
|  |               style={{ | ||||||
|  |                 paddingBottom: 0, | ||||||
|  |                 width: "100%", | ||||||
|  |                 overflow: "auto", | ||||||
|  |                 scrollbarWidth: "thin", | ||||||
|  |                 height: "calc(100% - 30px)", | ||||||
|  |                 margin: "15px 0", | ||||||
|  |                 paddingTop: 0, | ||||||
|  |                 whiteSpace: "pre-wrap", | ||||||
|  |                 backgroundColor: "white", | ||||||
|  |               }} | ||||||
|  |             > | ||||||
|  |               <code className="language-xml">{`${this.props.xml}`}</code> | ||||||
|             </pre> |             </pre> | ||||||
|           </AccordionDetails> |           </AccordionDetails> | ||||||
|         </Accordion> |         </Accordion> | ||||||
|       </Card> |       </Card> | ||||||
|     ); |     ); | ||||||
|   }; |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| CodeViewer.propTypes = { | CodeViewer.propTypes = { | ||||||
|   arduino: PropTypes.string.isRequired, |   arduino: PropTypes.string.isRequired, | ||||||
|   xml: 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, |   arduino: state.workspace.code.arduino, | ||||||
|   xml: state.workspace.code.xml, |   xml: state.workspace.code.xml, | ||||||
|   tooltip: state.workspace.code.tooltip |   tooltip: state.workspace.code.tooltip, | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| export default connect(mapStateToProps, null)(withWidth()(CodeViewer)); | export default connect(mapStateToProps, null)(withWidth()(CodeViewer)); | ||||||
|  | |||||||
| @ -4,7 +4,6 @@ import { connect } from "react-redux"; | |||||||
| import { workspaceName } from "../../actions/workspaceActions"; | import { workspaceName } from "../../actions/workspaceActions"; | ||||||
| 
 | 
 | ||||||
| import BlocklyWindow from "../Blockly/BlocklyWindow"; | import BlocklyWindow from "../Blockly/BlocklyWindow"; | ||||||
| import CodeViewer from "../CodeViewer"; |  | ||||||
| import WorkspaceFunc from "../Workspace/WorkspaceFunc"; | import WorkspaceFunc from "../Workspace/WorkspaceFunc"; | ||||||
| 
 | 
 | ||||||
| import withWidth, { isWidthDown } from "@material-ui/core/withWidth"; | 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 Typography from "@material-ui/core/Typography"; | ||||||
| import * as Blockly from "blockly"; | import * as Blockly from "blockly"; | ||||||
| import { initialXml } from "../Blockly/initialXml"; | 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 { | class Assessment extends Component { | ||||||
|  |   constructor(props) { | ||||||
|  |     super(props); | ||||||
|  |     this.state = { | ||||||
|  |       codeOn: false, | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   componentDidMount() { |   componentDidMount() { | ||||||
|     this.props.workspaceName(this.props.name); |     this.props.workspaceName(this.props.name); | ||||||
|   } |   } | ||||||
| @ -25,6 +60,10 @@ class Assessment extends Component { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   onChange = () => { | ||||||
|  |     this.setState({ codeOn: !this.state.codeOn }); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|   render() { |   render() { | ||||||
|     var tutorialId = this.props.tutorial._id; |     var tutorialId = this.props.tutorial._id; | ||||||
|     var currentTask = this.props.step; |     var currentTask = this.props.step; | ||||||
| @ -38,50 +77,41 @@ class Assessment extends Component { | |||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|       <div className="assessmentDiv" style={{ width: "100%" }}> |       <div className="assessmentDiv" style={{ width: "100%" }}> | ||||||
|         <Typography |  | ||||||
|           variant="h4" |  | ||||||
|           style={{ |  | ||||||
|             float: "left", |  | ||||||
|             marginBottom: "5px", |  | ||||||
|             height: "40px", |  | ||||||
|             display: "table", |  | ||||||
|           }} |  | ||||||
|         > |  | ||||||
|           {currentTask.headline} |  | ||||||
|         </Typography> |  | ||||||
|         <div style={{ float: "right", height: "40px" }}> |         <div style={{ float: "right", height: "40px" }}> | ||||||
|           <WorkspaceFunc assessment /> |           <WorkspaceFunc assessment /> | ||||||
|         </div> |         </div> | ||||||
|         <Grid container spacing={2} style={{ marginBottom: "5px" }}> |         <Grid container spacing={2} style={{ marginBottom: "5px" }}> | ||||||
|           <Grid item xs={12} md={6} lg={8}> |  | ||||||
|             <BlocklyWindow |  | ||||||
|               initialXml={initialXml} |  | ||||||
|               blockDisabled |  | ||||||
|               blocklyCSS={{ height: "65vH" }} |  | ||||||
|             /> |  | ||||||
|           </Grid> |  | ||||||
|           <Grid |           <Grid | ||||||
|             item |             item | ||||||
|             xs={12} |             xs={12} | ||||||
|             md={6} |             md={6} | ||||||
|             lg={4} |             lg={3} | ||||||
|             style={ |             style={{ | ||||||
|               isWidthDown("sm", this.props.width) |               position: "relative", | ||||||
|                 ? { height: "max-content" } |               // isWidthDown("sm", this.props.width)
 | ||||||
|                 : {} |               //   ? { height: "max-content" }
 | ||||||
|             } |               //   : {}
 | ||||||
|  |             }} | ||||||
|           > |           > | ||||||
|             <Card |             <Card | ||||||
|               style={{ |               style={{ | ||||||
|                 height: "calc(50% - 30px)", |                 height: "calc(45vH - 30px)", | ||||||
|                 padding: "10px", |                 padding: "10px", | ||||||
|                 marginBottom: "10px", |                 marginBottom: "10px", | ||||||
|               }} |               }} | ||||||
|             > |             > | ||||||
|               <Typography variant="h5"> |               <Typography> | ||||||
|                 {Blockly.Msg.tutorials_assessment_task} |                 <ReactMarkdown>{currentTask.text}</ReactMarkdown> | ||||||
|               </Typography> |               </Typography> | ||||||
|               <Typography>{currentTask.text}</Typography> |             </Card> | ||||||
|  |             <Card | ||||||
|  |               style={{ | ||||||
|  |                 height: "20vH", | ||||||
|  |                 padding: "10px", | ||||||
|  |                 marginBottom: "10px", | ||||||
|  |               }} | ||||||
|  |             > | ||||||
|  |               <TooltipViewer /> | ||||||
|             </Card> |             </Card> | ||||||
|             <div |             <div | ||||||
|               style={ |               style={ | ||||||
| @ -89,10 +119,52 @@ class Assessment extends Component { | |||||||
|                   ? { height: "500px" } |                   ? { height: "500px" } | ||||||
|                   : { height: "50%" } |                   : { height: "50%" } | ||||||
|               } |               } | ||||||
|             > |             ></div> | ||||||
|               <CodeViewer /> |  | ||||||
|             </div> |  | ||||||
|           </Grid> |           </Grid> | ||||||
|  |           <Grid | ||||||
|  |             item | ||||||
|  |             xs={12} | ||||||
|  |             md={this.state.codeOn ? 6 : 6} | ||||||
|  |             lg={this.state.codeOn ? 6 : 9} | ||||||
|  |             style={{ position: "relative" }} | ||||||
|  |           > | ||||||
|  |             <Tooltip | ||||||
|  |               title={ | ||||||
|  |                 this.state.codeOn | ||||||
|  |                   ? Blockly.Msg.tooltip_hide_code | ||||||
|  |                   : Blockly.Msg.tooltip_show_code | ||||||
|  |               } | ||||||
|  |             > | ||||||
|  |               <IconButton | ||||||
|  |                 className={`showCode ${ | ||||||
|  |                   this.state.codeOn | ||||||
|  |                     ? this.props.classes.codeOn | ||||||
|  |                     : this.props.classes.codeOff | ||||||
|  |                 }`}
 | ||||||
|  |                 style={{ | ||||||
|  |                   width: "40px", | ||||||
|  |                   height: "40px", | ||||||
|  |                   position: "absolute", | ||||||
|  |                   top: 6, | ||||||
|  |                   right: 8, | ||||||
|  |                   zIndex: 21, | ||||||
|  |                 }} | ||||||
|  |                 onClick={() => this.onChange()} | ||||||
|  |               > | ||||||
|  |                 <FontAwesomeIcon icon={faCode} size="xs" /> | ||||||
|  |               </IconButton> | ||||||
|  |             </Tooltip> | ||||||
|  |             <BlocklyWindow | ||||||
|  |               initialXml={initialXml} | ||||||
|  |               blockDisabled | ||||||
|  |               blocklyCSS={{ height: "65vH" }} | ||||||
|  |             /> | ||||||
|  |           </Grid> | ||||||
|  |           {this.state.codeOn ? ( | ||||||
|  |             <Grid item xs={12} md={4} lg={3}> | ||||||
|  |               <CodeViewer /> | ||||||
|  |             </Grid> | ||||||
|  |           ) : null} | ||||||
|         </Grid> |         </Grid> | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
| @ -113,5 +185,5 @@ const mapStateToProps = (state) => ({ | |||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| export default connect(mapStateToProps, { workspaceName })( | export default connect(mapStateToProps, { workspaceName })( | ||||||
|   withWidth()(Assessment) |   withWidth()(withStyles(styles, { withTheme: true })(Assessment)) | ||||||
| ); | ); | ||||||
|  | |||||||
| @ -15,9 +15,9 @@ class Instruction extends Component { | |||||||
|     var areRequirements = step.requirements && step.requirements.length > 0; |     var areRequirements = step.requirements && step.requirements.length > 0; | ||||||
|     return ( |     return ( | ||||||
|       <div> |       <div> | ||||||
|         <Typography variant="h4" style={{ marginBottom: "5px" }}> |         {/* <Typography variant="h4" style={{ marginBottom: "5px" }}> | ||||||
|           {step.headline} |           {step.headline} | ||||||
|         </Typography> |         </Typography> */} | ||||||
|         <Typography style={isHardware ? {} : { marginBottom: "5px" }}> |         <Typography style={isHardware ? {} : { marginBottom: "5px" }}> | ||||||
|           <ReactMarkdown |           <ReactMarkdown | ||||||
|             className={"tutorial"} |             className={"tutorial"} | ||||||
|  | |||||||
| @ -1,31 +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 { withRouter } from 'react-router-dom'; | import { withRouter } from "react-router-dom"; | ||||||
| 
 | 
 | ||||||
| import clsx from 'clsx'; | import clsx from "clsx"; | ||||||
| 
 | 
 | ||||||
| // import tutorials from '../../data/tutorials';
 | // import tutorials from '../../data/tutorials';
 | ||||||
| 
 | 
 | ||||||
| import { fade } from '@material-ui/core/styles/colorManipulator'; | import { fade } from "@material-ui/core/styles/colorManipulator"; | ||||||
| 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 Tooltip from '@material-ui/core/Tooltip'; | import Tooltip from "@material-ui/core/Tooltip"; | ||||||
| import Button from '@material-ui/core/Button'; | import Button from "@material-ui/core/Button"; | ||||||
| 
 | 
 | ||||||
| import { faCheck, faTimes } from "@fortawesome/free-solid-svg-icons"; | import { faCheck, faTimes } from "@fortawesome/free-solid-svg-icons"; | ||||||
| import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | ||||||
| 
 | 
 | ||||||
| const styles = (theme) => ({ | const styles = (theme) => ({ | ||||||
|   stepper: { |   stepper: { | ||||||
|     width: 'calc(100% - 40px)', |     width: "calc(100% - 40px)", | ||||||
|     height: '40px', |     height: "40px", | ||||||
|     borderRadius: '25px', |     borderRadius: "25px", | ||||||
|     padding: '0 20px', |     padding: "0 20px", | ||||||
|     margin: '20px 0', |     margin: "20px 0", | ||||||
|     display: 'flex', |     display: "flex", | ||||||
|     justifyContent: 'space-between' |     justifyContent: "space-between", | ||||||
|   }, |   }, | ||||||
|   stepperSuccess: { |   stepperSuccess: { | ||||||
|     backgroundColor: fade(theme.palette.primary.main, 0.6), |     backgroundColor: fade(theme.palette.primary.main, 0.6), | ||||||
| @ -37,73 +37,147 @@ const styles = (theme) => ({ | |||||||
|     backgroundColor: fade(theme.palette.secondary.main, 0.6), |     backgroundColor: fade(theme.palette.secondary.main, 0.6), | ||||||
|   }, |   }, | ||||||
|   color: { |   color: { | ||||||
|     backgroundColor: 'transparent ' |     backgroundColor: "transparent ", | ||||||
|   }, |   }, | ||||||
|   iconDivSuccess: { |   iconDivSuccess: { | ||||||
|     color: theme.palette.primary.main |     color: theme.palette.primary.main, | ||||||
|   }, |   }, | ||||||
|   iconDivError: { |   iconDivError: { | ||||||
|     color: theme.palette.error.dark |     color: theme.palette.error.dark, | ||||||
|   } |   }, | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| class StepperHorizontal extends Component { | class StepperHorizontal extends Component { | ||||||
| 
 |  | ||||||
|   render() { |   render() { | ||||||
|     var tutorialId = this.props.tutorial._id; |     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 tasks = status.tasks; | ||||||
|     var error = tasks.filter(task => task.type === 'error').length > 0; |     var error = tasks.filter((task) => task.type === "error").length > 0; | ||||||
|     var success = tasks.filter(task => task.type === 'success').length / tasks.length; |     var success = | ||||||
|     var tutorialStatus = success === 1 ? 'Success' : error ? 'Error' : 'Other'; |       tasks.filter((task) => task.type === "success").length / tasks.length; | ||||||
|  |     var tutorialStatus = success === 1 ? "Success" : error ? "Error" : "Other"; | ||||||
|     var title = this.props.tutorial.title; |     var title = this.props.tutorial.title; | ||||||
|  |     var activeStep = this.props.activeStep; | ||||||
|     return ( |     return ( | ||||||
|       <div style={{ position: 'relative' }}> |       <div style={{ position: "relative" }}> | ||||||
|         {error || success > 0 ? |         {error || success > 0 ? ( | ||||||
|           <div style={{ zIndex: -1, width: error ? 'calc(100% - 40px)' : `calc(${success * 100}% - 40px)`, borderRadius: success === 1 || error ? '25px' : '25px 0 0 25px', position: 'absolute', margin: 0, left: 0 }} className={clsx(this.props.classes.stepper, error ? this.props.classes.stepperError : this.props.classes.stepperSuccess)}> |           <div | ||||||
|           </div> |             style={{ | ||||||
|           : null} |               zIndex: -1, | ||||||
|         {success < 1 && !error ? |               width: error | ||||||
|           <div style={{ zIndex: -2, width: `calc(${(1 - success) * 100}% - 40px)`, borderRadius: success === 0 ? '25px' : '0px 25px 25px 0', position: 'absolute', margin: 0, right: 0 }} className={clsx(this.props.classes.stepper, this.props.classes.stepperOther)}> |                 ? "calc(100% - 40px)" | ||||||
|           </div> |                 : `calc(${success * 100}% - 40px)`, | ||||||
|           : null} |               borderRadius: success === 1 || error ? "25px" : "25px 0 0 25px", | ||||||
|  |               position: "absolute", | ||||||
|  |               margin: 0, | ||||||
|  |               left: 0, | ||||||
|  |             }} | ||||||
|  |             className={clsx( | ||||||
|  |               this.props.classes.stepper, | ||||||
|  |               error | ||||||
|  |                 ? this.props.classes.stepperError | ||||||
|  |                 : this.props.classes.stepperSuccess | ||||||
|  |             )} | ||||||
|  |           ></div> | ||||||
|  |         ) : null} | ||||||
|  |         {success < 1 && !error ? ( | ||||||
|  |           <div | ||||||
|  |             style={{ | ||||||
|  |               zIndex: -2, | ||||||
|  |               width: `calc(${(1 - success) * 100}% - 40px)`, | ||||||
|  |               borderRadius: success === 0 ? "25px" : "0px 25px 25px 0", | ||||||
|  |               position: "absolute", | ||||||
|  |               margin: 0, | ||||||
|  |               right: 0, | ||||||
|  |             }} | ||||||
|  |             className={clsx( | ||||||
|  |               this.props.classes.stepper, | ||||||
|  |               this.props.classes.stepperOther | ||||||
|  |             )} | ||||||
|  |           ></div> | ||||||
|  |         ) : null} | ||||||
|         <div className={this.props.classes.stepper}> |         <div className={this.props.classes.stepper}> | ||||||
|           <Button |           <Button | ||||||
|             disabled//={tutorialIndex === 0}
 |             disabled //={tutorialIndex === 0}
 | ||||||
|             //onClick={() => { this.props.history.push(`/tutorial/${tutorials[tutorialIndex - 1].id}`) }}
 |             //onClick={() => { this.props.history.push(`/tutorial/${tutorials[tutorialIndex - 1].id}`) }}
 | ||||||
|           > |           > | ||||||
|             {'<'} |             {"<"} | ||||||
|           </Button> |           </Button> | ||||||
|           <Tooltip style={{ display: 'flex', width: 'calc(100% - 64px - 64px)', justifyContent: 'center' }} title={title} arrow> |           <Tooltip | ||||||
|  |             style={{ | ||||||
|  |               display: "flex", | ||||||
|  |               width: "calc(100% - 64px - 64px)", | ||||||
|  |               justifyContent: "center", | ||||||
|  |             }} | ||||||
|  |             title={title} | ||||||
|  |             arrow | ||||||
|  |           > | ||||||
|             <div> |             <div> | ||||||
|               {tutorialStatus !== 'Other' ? <div className={tutorialStatus === 'Success' && success === 1 ? this.props.classes.iconDivSuccess : this.props.classes.iconDivError} style={{ margin: 'auto 10px auto 0' }}><FontAwesomeIcon className={this.props.classes.icon} icon={tutorialStatus === 'Success' ? faCheck : faTimes} /></div> : null} |               {tutorialStatus !== "Other" ? ( | ||||||
|               <Typography variant='body2' style={{ fontWeight: 'bold', fontSize: '1.75em', margin: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', color: 'rgba(0, 0, 0, 0.54)' }}>{title}</Typography> |                 <div | ||||||
|  |                   className={ | ||||||
|  |                     tutorialStatus === "Success" && success === 1 | ||||||
|  |                       ? this.props.classes.iconDivSuccess | ||||||
|  |                       : this.props.classes.iconDivError | ||||||
|  |                   } | ||||||
|  |                   style={{ margin: "auto 10px auto 0" }} | ||||||
|  |                 > | ||||||
|  |                   <FontAwesomeIcon | ||||||
|  |                     className={this.props.classes.icon} | ||||||
|  |                     icon={tutorialStatus === "Success" ? faCheck : faTimes} | ||||||
|  |                   /> | ||||||
|  |                 </div> | ||||||
|  |               ) : null} | ||||||
|  |               <Typography | ||||||
|  |                 variant="body2" | ||||||
|  |                 style={{ | ||||||
|  |                   fontWeight: "bold", | ||||||
|  |                   fontSize: "1.75em", | ||||||
|  |                   margin: 0, | ||||||
|  |                   overflow: "hidden", | ||||||
|  |                   textOverflow: "ellipsis", | ||||||
|  |                   whiteSpace: "nowrap", | ||||||
|  |                   color: "rgba(0, 0, 0, 0.54)", | ||||||
|  |                 }} | ||||||
|  |               > | ||||||
|  |                 {title} | ||||||
|  |                 {title !== this.props.tutorial.steps[activeStep].headline | ||||||
|  |                   ? ` - ${this.props.tutorial.steps[activeStep].headline}` | ||||||
|  |                   : null} | ||||||
|  |               </Typography> | ||||||
|             </div> |             </div> | ||||||
|           </Tooltip> |           </Tooltip> | ||||||
|           <Button |           <Button | ||||||
|             disabled//={tutorialIndex + 1 === tutorials.length}
 |             disabled //={tutorialIndex + 1 === tutorials.length}
 | ||||||
|             //onClick={() => { this.props.history.push(`/tutorial/${tutorials[tutorialIndex + 1].id}`) }}
 |             //onClick={() => { this.props.history.push(`/tutorial/${tutorials[tutorialIndex + 1].id}`) }}
 | ||||||
|           > |           > | ||||||
|             {'>'} |             {">"} | ||||||
|           </Button> |           </Button> | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
|   }; |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| StepperHorizontal.propTypes = { | StepperHorizontal.propTypes = { | ||||||
|   status: PropTypes.array.isRequired, |   status: PropTypes.array.isRequired, | ||||||
|   change: PropTypes.number.isRequired, |   change: PropTypes.number.isRequired, | ||||||
|   currentTutorialIndex: 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, |   change: state.tutorial.change, | ||||||
|   status: state.tutorial.status, |   status: state.tutorial.status, | ||||||
|   currentTutorialIndex: state.tutorial.currentIndex, |   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))); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user