get a tutorial about the API
This commit is contained in:
		
							parent
							
								
									28d674b6cd
								
							
						
					
					
						commit
						ea00d173c5
					
				| @ -13,6 +13,7 @@ | |||||||
|     "@testing-library/jest-dom": "^4.2.4", |     "@testing-library/jest-dom": "^4.2.4", | ||||||
|     "@testing-library/react": "^9.5.0", |     "@testing-library/react": "^9.5.0", | ||||||
|     "@testing-library/user-event": "^7.2.1", |     "@testing-library/user-event": "^7.2.1", | ||||||
|  |     "axios": "^0.21.0", | ||||||
|     "blockly": "^3.20200924.0", |     "blockly": "^3.20200924.0", | ||||||
|     "file-saver": "^2.0.2", |     "file-saver": "^2.0.2", | ||||||
|     "mnemonic-id": "^3.2.7", |     "mnemonic-id": "^3.2.7", | ||||||
|  | |||||||
							
								
								
									
										32
									
								
								src/actions/messageActions.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/actions/messageActions.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | import { GET_ERRORS, CLEAR_MESSAGES, GET_SUCCESS } from './types'; | ||||||
|  | 
 | ||||||
|  | // RETURN Errors
 | ||||||
|  | export const returnErrors = (msg, status, id = null) => { | ||||||
|  |   return { | ||||||
|  |     type: GET_ERRORS, | ||||||
|  |     payload: { | ||||||
|  |       msg: msg, | ||||||
|  |       status: status, | ||||||
|  |       id: id | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // RETURN Success
 | ||||||
|  | export const returnSuccess = (msg, status, id = null) => { | ||||||
|  |   return { | ||||||
|  |     type: GET_SUCCESS, | ||||||
|  |     payload: { | ||||||
|  |       msg: msg, | ||||||
|  |       status: status, | ||||||
|  |       id: id | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // CLEAR_MESSAGES
 | ||||||
|  | export const clearMessages = () => { | ||||||
|  |   return { | ||||||
|  |     type: CLEAR_MESSAGES | ||||||
|  |   }; | ||||||
|  | }; | ||||||
| @ -1,6 +1,34 @@ | |||||||
| import { TUTORIAL_SUCCESS, TUTORIAL_ERROR, TUTORIAL_CHANGE, TUTORIAL_XML, TUTORIAL_ID, TUTORIAL_STEP } from './types'; | import { TUTORIAL_PROGRESS, GET_TUTORIAL, TUTORIAL_SUCCESS, TUTORIAL_ERROR, TUTORIAL_CHANGE, TUTORIAL_XML, TUTORIAL_ID, TUTORIAL_STEP } from './types'; | ||||||
| 
 | 
 | ||||||
| import tutorials from '../data/tutorials'; | import axios from 'axios'; | ||||||
|  | import { returnErrors, returnSuccess } from './messageActions'; | ||||||
|  | 
 | ||||||
|  | // import tutorials from '../data/tutorials';
 | ||||||
|  | 
 | ||||||
|  | export const getTutorial = (id) => (dispatch) => { | ||||||
|  |   dispatch({type: TUTORIAL_PROGRESS}); | ||||||
|  |   axios.get(`https://api.blockly.sensebox.de/tutorial/${id}`) | ||||||
|  |     .then(res => { | ||||||
|  |       dispatch({type: TUTORIAL_PROGRESS}); | ||||||
|  |       dispatch({ | ||||||
|  |         type: GET_TUTORIAL, | ||||||
|  |         payload: res.data | ||||||
|  |       }); | ||||||
|  |     }) | ||||||
|  |     .catch(err => { | ||||||
|  |       dispatch({type: TUTORIAL_PROGRESS}); | ||||||
|  |       if(err.response){ | ||||||
|  |         dispatch(returnErrors(err.response.data.message, err.response.status, 'GET_TUTORIAL_FAIL')); | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export const resetTutorial = () => (dispatch) => { | ||||||
|  |   dispatch({ | ||||||
|  |     type: GET_TUTORIAL, | ||||||
|  |     payload: {} | ||||||
|  |   }); | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| export const tutorialChange = () => (dispatch) => { | export const tutorialChange = () => (dispatch) => { | ||||||
|   dispatch({ |   dispatch({ | ||||||
| @ -10,7 +38,7 @@ export const tutorialChange = () => (dispatch) => { | |||||||
| 
 | 
 | ||||||
| export const tutorialCheck = (status, step) => (dispatch, getState) => { | export const tutorialCheck = (status, step) => (dispatch, getState) => { | ||||||
|   var tutorialsStatus = getState().tutorial.status; |   var tutorialsStatus = getState().tutorial.status; | ||||||
|   var id = getState().tutorial.currentId; |   var id = getState().tutorial.tutorial.id; | ||||||
|   var tutorialsStatusIndex = tutorialsStatus.findIndex(tutorialStatus => tutorialStatus.id === id); |   var tutorialsStatusIndex = tutorialsStatus.findIndex(tutorialStatus => tutorialStatus.id === id); | ||||||
|   var tasksIndex = tutorialsStatus[tutorialsStatusIndex].tasks.findIndex(task => task.id === step.id); |   var tasksIndex = tutorialsStatus[tutorialsStatusIndex].tasks.findIndex(task => task.id === step.id); | ||||||
|   tutorialsStatus[tutorialsStatusIndex].tasks[tasksIndex] = { |   tutorialsStatus[tutorialsStatusIndex].tasks[tasksIndex] = { | ||||||
| @ -25,11 +53,12 @@ export const tutorialCheck = (status, step) => (dispatch, getState) => { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export const storeTutorialXml = (code) => (dispatch, getState) => { | export const storeTutorialXml = (code) => (dispatch, getState) => { | ||||||
|   var id = getState().tutorial.currentId; |   var tutorial = getState().tutorial.tutorial; | ||||||
|  |   var id = tutorial.id; | ||||||
|   if (id !== null) { |   if (id !== null) { | ||||||
|     var activeStep = getState().tutorial.activeStep; |     var activeStep = getState().tutorial.activeStep; | ||||||
|     var steps = tutorials.filter(tutorial => tutorial.id === id)[0].steps; |     var steps = tutorial.steps;//tutorials.filter(tutorial => tutorial.id === id)[0].steps;
 | ||||||
|     if (steps[activeStep].type === 'task') { |     if (steps && steps[activeStep].type === 'task') { | ||||||
|       var tutorialsStatus = getState().tutorial.status; |       var tutorialsStatus = getState().tutorial.status; | ||||||
|       var tutorialsStatusIndex = tutorialsStatus.findIndex(tutorialStatus => tutorialStatus.id === id); |       var tutorialsStatusIndex = tutorialsStatus.findIndex(tutorialStatus => tutorialStatus.id === id); | ||||||
|       var tasksIndex = tutorialsStatus[tutorialsStatusIndex].tasks.findIndex(task => task.id === steps[activeStep].id); |       var tasksIndex = tutorialsStatus[tutorialsStatusIndex].tasks.findIndex(task => task.id === steps[activeStep].id); | ||||||
| @ -46,12 +75,12 @@ export const storeTutorialXml = (code) => (dispatch, getState) => { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| export const tutorialId = (id) => (dispatch) => { | // export const tutorialId = (id) => (dispatch) => {
 | ||||||
|   dispatch({ | //   dispatch({
 | ||||||
|     type: TUTORIAL_ID, | //     type: TUTORIAL_ID,
 | ||||||
|     payload: id | //     payload: id
 | ||||||
|   }); | //   });
 | ||||||
| }; | // };
 | ||||||
| 
 | 
 | ||||||
| export const tutorialStep = (step) => (dispatch) => { | export const tutorialStep = (step) => (dispatch) => { | ||||||
|   dispatch({ |   dispatch({ | ||||||
|  | |||||||
| @ -7,7 +7,8 @@ export const DELETE_BLOCK = 'DELETE_BLOCK'; | |||||||
| export const CLEAR_STATS = 'CLEAR_STATS'; | export const CLEAR_STATS = 'CLEAR_STATS'; | ||||||
| export const NAME = 'NAME'; | export const NAME = 'NAME'; | ||||||
| 
 | 
 | ||||||
| 
 | export const TUTORIAL_PROGRESS = 'TUTORIAL_PROGRESS'; | ||||||
|  | export const GET_TUTORIAL = 'GET_TUTORIAL'; | ||||||
| export const TUTORIAL_SUCCESS = 'TUTORIAL_SUCCESS'; | export const TUTORIAL_SUCCESS = 'TUTORIAL_SUCCESS'; | ||||||
| export const TUTORIAL_ERROR = 'TUTORIAL_ERROR'; | export const TUTORIAL_ERROR = 'TUTORIAL_ERROR'; | ||||||
| export const TUTORIAL_CHANGE = 'TUTORIAL_CHANGE'; | export const TUTORIAL_CHANGE = 'TUTORIAL_CHANGE'; | ||||||
| @ -30,3 +31,8 @@ export const PROGRESS = 'PROGRESS'; | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| export const VISIT = 'VISIT'; | export const VISIT = 'VISIT'; | ||||||
|  | 
 | ||||||
|  | // messages
 | ||||||
|  | export const GET_ERRORS = 'GET_ERRORS'; | ||||||
|  | export const GET_SUCCESS = 'GET_SUCCESS'; | ||||||
|  | export const CLEAR_MESSAGES = 'CLEAR_MESSAGES'; | ||||||
|  | |||||||
| @ -27,7 +27,7 @@ class Assessment extends Component { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   render() { |   render() { | ||||||
|     var tutorialId = this.props.currentTutorialId; |     var tutorialId = this.props.tutorial.id //currentTutorialId;
 | ||||||
|     var currentTask = this.props.step; |     var currentTask = this.props.step; | ||||||
|     var status = this.props.status.filter(status => status.id === tutorialId)[0]; |     var status = this.props.status.filter(status => status.id === tutorialId)[0]; | ||||||
|     var taskIndex = status.tasks.findIndex(task => task.id === currentTask.id); |     var taskIndex = status.tasks.findIndex(task => task.id === currentTask.id); | ||||||
| @ -61,16 +61,18 @@ class Assessment extends Component { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Assessment.propTypes = { | Assessment.propTypes = { | ||||||
|   currentTutorialId: PropTypes.number, |   // currentTutorialId: PropTypes.number,
 | ||||||
|   status: PropTypes.array.isRequired, |   status: PropTypes.array.isRequired, | ||||||
|   change: PropTypes.number.isRequired, |   change: PropTypes.number.isRequired, | ||||||
|   workspaceName: PropTypes.func.isRequired |   workspaceName: PropTypes.func.isRequired, | ||||||
|  |   tutorial: PropTypes.object.isRequired | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const mapStateToProps = state => ({ | const mapStateToProps = state => ({ | ||||||
|   change: state.tutorial.change, |   change: state.tutorial.change, | ||||||
|   status: state.tutorial.status, |   status: state.tutorial.status, | ||||||
|   currentTutorialId: state.tutorial.currentId |   tutorial: state.tutorial.tutorial | ||||||
|  |   // currentTutorialId: state.tutorial.currentId
 | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| export default connect(mapStateToProps, { workspaceName })(withWidth()(Assessment)); | export default connect(mapStateToProps, { workspaceName })(withWidth()(Assessment)); | ||||||
|  | |||||||
| @ -56,11 +56,11 @@ class Instruction extends Component { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Instruction.propTypes = { | Instruction.propTypes = { | ||||||
|   currentTutorialId: PropTypes.number, |   // currentTutorialId: PropTypes.number,
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const mapStateToProps = state => ({ | const mapStateToProps = state => ({ | ||||||
|   currentTutorialId: state.tutorial.currentId |   // currentTutorialId: state.tutorial.currentId
 | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| export default connect(mapStateToProps, null)(Instruction); | export default connect(mapStateToProps, null)(Instruction); | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ import { withRouter } from 'react-router-dom'; | |||||||
| import Compile from '../Compile'; | import Compile from '../Compile'; | ||||||
| import Dialog from '../Dialog'; | import Dialog from '../Dialog'; | ||||||
| 
 | 
 | ||||||
| import tutorials from '../../data/tutorials'; | // import tutorials from '../../data/tutorials';
 | ||||||
| import { checkXml } from '../../helpers/compareXml'; | import { checkXml } from '../../helpers/compareXml'; | ||||||
| 
 | 
 | ||||||
| import { withStyles } from '@material-ui/core/styles'; | import { withStyles } from '@material-ui/core/styles'; | ||||||
| @ -47,7 +47,7 @@ class SolutionCheck extends Component { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   check = () => { |   check = () => { | ||||||
|     const tutorial = tutorials.filter(tutorial => tutorial.id === this.props.currentTutorialId)[0]; |     const tutorial = this.props.tutorial //tutorials.filter(tutorial => tutorial.id === this.props.currentTutorialId)[0];
 | ||||||
|     const step = tutorial.steps[this.props.activeStep]; |     const step = tutorial.steps[this.props.activeStep]; | ||||||
|     var msg = checkXml(step.xml, this.props.xml); |     var msg = checkXml(step.xml, this.props.xml); | ||||||
|     this.props.tutorialCheck(msg.type, step); |     this.props.tutorialCheck(msg.type, step); | ||||||
| @ -55,7 +55,7 @@ class SolutionCheck extends Component { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   render() { |   render() { | ||||||
|     const steps = tutorials.filter(tutorial => tutorial.id === this.props.currentTutorialId)[0].steps; |     const steps = this.props.tutorial.steps //tutorials.filter(tutorial => tutorial.id === this.props.currentTutorialId)[0].steps;
 | ||||||
|     return ( |     return ( | ||||||
|       <div> |       <div> | ||||||
|         <Tooltip title='Lösung kontrollieren' arrow> |         <Tooltip title='Lösung kontrollieren' arrow> | ||||||
| @ -114,15 +114,17 @@ class SolutionCheck extends Component { | |||||||
| SolutionCheck.propTypes = { | SolutionCheck.propTypes = { | ||||||
|   tutorialCheck: PropTypes.func.isRequired, |   tutorialCheck: PropTypes.func.isRequired, | ||||||
|   tutorialStep: PropTypes.func.isRequired, |   tutorialStep: PropTypes.func.isRequired, | ||||||
|   currentTutorialId: PropTypes.number, |   // currentTutorialId: PropTypes.number,
 | ||||||
|   activeStep: PropTypes.number.isRequired, |   activeStep: PropTypes.number.isRequired, | ||||||
|   xml: PropTypes.string.isRequired |   xml: PropTypes.string.isRequired, | ||||||
|  |   tutorial: PropTypes.object.isRequired | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const mapStateToProps = state => ({ | const mapStateToProps = state => ({ | ||||||
|   currentTutorialId: state.tutorial.currentId, |   // currentTutorialId: state.tutorial.currentId,
 | ||||||
|   activeStep: state.tutorial.activeStep, |   activeStep: state.tutorial.activeStep, | ||||||
|   xml: state.workspace.code.xml |   xml: state.workspace.code.xml, | ||||||
|  |   tutorial: state.tutorial.tutorial | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| export default connect(mapStateToProps, { tutorialCheck, tutorialStep })(withStyles(styles, { withTheme: true })(withRouter(SolutionCheck))); | export default connect(mapStateToProps, { tutorialCheck, tutorialStep })(withStyles(styles, { withTheme: true })(withRouter(SolutionCheck))); | ||||||
|  | |||||||
| @ -50,14 +50,14 @@ const styles = (theme) => ({ | |||||||
| class StepperHorizontal extends Component { | class StepperHorizontal extends Component { | ||||||
| 
 | 
 | ||||||
|   render() { |   render() { | ||||||
|     var tutorialId = this.props.currentTutorialId; |     var tutorialId = this.props.tutorial.id //this.props.currentTutorialId;
 | ||||||
|     var tutorialIndex = this.props.currentTutorialIndex; |     var tutorialIndex = this.props.currentTutorialIndex; | ||||||
|     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 = tasks.filter(task => task.type === 'success').length / tasks.length; | ||||||
|     var tutorialStatus = success === 1 ? 'Success' : error ? 'Error' : 'Other'; |     var tutorialStatus = success === 1 ? 'Success' : error ? 'Error' : 'Other'; | ||||||
|     var title = tutorials.filter(tutorial => tutorial.id === tutorialId)[0].title; |     var title = this.props.tutorial.title; | ||||||
|     return ( |     return ( | ||||||
|       <div style={{ position: 'relative' }}> |       <div style={{ position: 'relative' }}> | ||||||
|         {error || success > 0 ? |         {error || success > 0 ? | ||||||
| @ -96,15 +96,17 @@ class StepperHorizontal extends Component { | |||||||
| StepperHorizontal.propTypes = { | StepperHorizontal.propTypes = { | ||||||
|   status: PropTypes.array.isRequired, |   status: PropTypes.array.isRequired, | ||||||
|   change: PropTypes.number.isRequired, |   change: PropTypes.number.isRequired, | ||||||
|   currentTutorialId: PropTypes.number.isRequired, |   // currentTutorialId: PropTypes.number.isRequired,
 | ||||||
|   currentTutorialIndex: PropTypes.number.isRequired |   currentTutorialIndex: PropTypes.number.isRequired, | ||||||
|  |   tutorial: PropTypes.object.isRequired | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const mapStateToProps = state => ({ | const mapStateToProps = state => ({ | ||||||
|   change: state.tutorial.change, |   change: state.tutorial.change, | ||||||
|   status: state.tutorial.status, |   status: state.tutorial.status, | ||||||
|   currentTutorialId: state.tutorial.currentId, |   // currentTutorialId: state.tutorial.currentId,
 | ||||||
|   currentTutorialIndex: state.tutorial.currentIndex |   currentTutorialIndex: state.tutorial.currentIndex, | ||||||
|  |   tutorial: state.tutorial.tutorial | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| export default connect(mapStateToProps, null)(withRouter(withStyles(styles, { withTheme: true })(StepperHorizontal))); | export default connect(mapStateToProps, null)(withRouter(withStyles(styles, { withTheme: true })(StepperHorizontal))); | ||||||
|  | |||||||
| @ -61,7 +61,7 @@ class StepperVertical extends Component { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   componentDidUpdate(props){ |   componentDidUpdate(props){ | ||||||
|     if(props.currentTutorialId !== Number(this.props.match.params.tutorialId)){ |     if (props.tutorial.id !== Number(this.props.match.params.tutorialId)) { | ||||||
|       this.props.tutorialStep(0); |       this.props.tutorialStep(0); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @ -69,7 +69,7 @@ class StepperVertical extends Component { | |||||||
|   render() { |   render() { | ||||||
|     var steps = this.props.steps; |     var steps = this.props.steps; | ||||||
|     var activeStep = this.props.activeStep; |     var activeStep = this.props.activeStep; | ||||||
|     var tutorialStatus = this.props.status.filter(status => status.id === this.props.currentTutorialId)[0]; |     var tutorialStatus = this.props.status.filter(status => status.id === this.props.tutorial.id/*currentTutorialId*/)[0]; | ||||||
|     return ( |     return ( | ||||||
|       <div style={{marginRight: '10px'}}> |       <div style={{marginRight: '10px'}}> | ||||||
|         <Stepper |         <Stepper | ||||||
| @ -113,16 +113,18 @@ class StepperVertical extends Component { | |||||||
| StepperVertical.propTypes = { | StepperVertical.propTypes = { | ||||||
|   status: PropTypes.array.isRequired, |   status: PropTypes.array.isRequired, | ||||||
|   change: PropTypes.number.isRequired, |   change: PropTypes.number.isRequired, | ||||||
|   currentTutorialId: PropTypes.number.isRequired, |   // currentTutorialId: PropTypes.number.isRequired,
 | ||||||
|   activeStep: PropTypes.number.isRequired, |   activeStep: PropTypes.number.isRequired, | ||||||
|   tutorialStep: PropTypes.func.isRequired |   tutorialStep: PropTypes.func.isRequired, | ||||||
|  |   tutorial: PropTypes.object.isRequired | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const mapStateToProps = state => ({ | const mapStateToProps = state => ({ | ||||||
|   change: state.tutorial.change, |   change: state.tutorial.change, | ||||||
|   status: state.tutorial.status, |   status: state.tutorial.status, | ||||||
|   currentTutorialId: state.tutorial.currentId, |   // currentTutorialId: state.tutorial.currentId,
 | ||||||
|   activeStep: state.tutorial.activeStep |   activeStep: state.tutorial.activeStep, | ||||||
|  |   tutorial: state.tutorial.tutorial | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| export default connect(mapStateToProps, { tutorialStep })(withRouter(withStyles(styles, {withTheme: true})(StepperVertical))); | export default connect(mapStateToProps, { tutorialStep })(withRouter(withStyles(styles, {withTheme: true})(StepperVertical))); | ||||||
|  | |||||||
| @ -2,7 +2,8 @@ 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 { workspaceName } from '../../actions/workspaceActions'; | import { workspaceName } from '../../actions/workspaceActions'; | ||||||
| import { tutorialId, tutorialStep } from '../../actions/tutorialActions'; | import { clearMessages } from '../../actions/messageActions'; | ||||||
|  | import { getTutorial, resetTutorial, tutorialStep } from '../../actions/tutorialActions'; | ||||||
| 
 | 
 | ||||||
| import Breadcrumbs from '../Breadcrumbs'; | import Breadcrumbs from '../Breadcrumbs'; | ||||||
| import StepperHorizontal from './StepperHorizontal'; | import StepperHorizontal from './StepperHorizontal'; | ||||||
| @ -13,79 +14,99 @@ import NotFound from '../NotFound'; | |||||||
| 
 | 
 | ||||||
| import { detectWhitespacesAndReturnReadableResult } from '../../helpers/whitespace'; | import { detectWhitespacesAndReturnReadableResult } from '../../helpers/whitespace'; | ||||||
| 
 | 
 | ||||||
| import tutorials from '../../data/tutorials'; | // import tutorials from '../../data/tutorials';
 | ||||||
| 
 | 
 | ||||||
| import Card from '@material-ui/core/Card'; | import Card from '@material-ui/core/Card'; | ||||||
| import Button from '@material-ui/core/Button'; | import Button from '@material-ui/core/Button'; | ||||||
|  | import LinearProgress from '@material-ui/core/LinearProgress'; | ||||||
| 
 | 
 | ||||||
| class Tutorial extends Component { | class Tutorial extends Component { | ||||||
| 
 | 
 | ||||||
|   componentDidMount() { |   componentDidMount() { | ||||||
|     this.props.tutorialId(Number(this.props.match.params.tutorialId)); |     this.props.getTutorial(this.props.match.params.tutorialId); | ||||||
|  |     // this.props.tutorialId(Number(this.props.match.params.tutorialId));
 | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   componentDidUpdate(props, state) { |   componentDidUpdate(props, state) { | ||||||
|     if (props.currentTutorialId !== Number(this.props.match.params.tutorialId)) { |     if (props.tutorial.id && !props.isLoading && Number(props.tutorial.id) !== Number(this.props.match.params.tutorialId)) { | ||||||
|       this.props.tutorialId(Number(this.props.match.params.tutorialId)); |       this.props.getTutorial(this.props.match.params.tutorialId); | ||||||
|  |       // this.props.tutorialId(Number(this.props.match.params.tutorialId));
 | ||||||
|  |     } | ||||||
|  |     if(this.props.message.id === 'GET_TUTORIAL_FAIL'){ | ||||||
|  |       alert(this.props.message.msg); | ||||||
|  |       this.props.clearMessages(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   componentWillUnmount() { |   componentWillUnmount() { | ||||||
|     this.props.tutorialId(null); |     this.props.resetTutorial(); | ||||||
|     this.props.workspaceName(null); |     this.props.workspaceName(null); | ||||||
|  |     if(this.props.message.msg){ | ||||||
|  |       this.props.clearMessages(); | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   render() { |   render() { | ||||||
|     var currentTutorialId = this.props.currentTutorialId; |  | ||||||
|     var tutorial = tutorials.filter(tutorial => tutorial.id === currentTutorialId)[0]; |  | ||||||
|     var steps = tutorial ? tutorial.steps : null; |  | ||||||
|     var step = steps ? steps[this.props.activeStep] : null; |  | ||||||
|     var name = step ? `${detectWhitespacesAndReturnReadableResult(tutorial.title)}_${detectWhitespacesAndReturnReadableResult(step.headline)}` : null; |  | ||||||
|     return ( |     return ( | ||||||
|       !Number.isInteger(currentTutorialId) || currentTutorialId < 1 || !tutorial ? |       <div> | ||||||
|         <NotFound button={{ title: 'Zurück zur Tutorials-Übersicht', link: '/tutorial' }} /> |         {this.props.isLoading ? <LinearProgress /> : | ||||||
|         : |           Object.keys(this.props.tutorial).length === 0 ? <NotFound button={{ title: 'Zurück zur Tutorials-Übersicht', link: '/tutorial' }} /> | ||||||
|         <div> |             : (() => { | ||||||
|           <Breadcrumbs content={[{ link: '/tutorial', title: 'Tutorial' }, { link: `/tutorial/${currentTutorialId}`, title: tutorial.title }]} /> |                 var tutorial = this.props.tutorial; | ||||||
|  |                 var steps = this.props.tutorial.steps; | ||||||
|  |                 var step = steps[this.props.activeStep]; | ||||||
|  |                 var name = `${detectWhitespacesAndReturnReadableResult(tutorial.title)}_${detectWhitespacesAndReturnReadableResult(step.headline)}`; | ||||||
|  |                 return( | ||||||
|  |                   <div> | ||||||
|  |                     <Breadcrumbs content={[{ link: '/tutorial', title: 'Tutorial' }, { link: `/tutorial/${this.props.tutorial.id}`, title: tutorial.title }]} /> | ||||||
| 
 | 
 | ||||||
|           <StepperHorizontal /> |                     <StepperHorizontal /> | ||||||
| 
 | 
 | ||||||
|           <div style={{ display: 'flex' }}> |                     <div style={{ display: 'flex' }}> | ||||||
|             <StepperVertical steps={steps} /> |                       <StepperVertical steps={steps} /> | ||||||
|             {/* calc(Card-padding: 10px + Button-height: 35px + Button-marginTop: 15px)*/} |                       {/* calc(Card-padding: 10px + Button-height: 35px + Button-marginTop: 15px)*/} | ||||||
|             <Card style={{ padding: '10px 10px 60px 10px', display: 'block', position: 'relative', height: 'max-content', width: '100%' }}> |                       <Card style={{ padding: '10px 10px 60px 10px', display: 'block', position: 'relative', height: 'max-content', width: '100%' }}> | ||||||
|               {step ? |                         {step ? | ||||||
|                 step.type === 'instruction' ? |                           step.type === 'instruction' ? | ||||||
|                   <Instruction step={step} /> |                             <Instruction step={step} /> | ||||||
|                   : <Assessment step={step} name={name} /> // if step.type === 'assessment'
 |                             : <Assessment step={step} name={name} /> // if step.type === 'assessment'
 | ||||||
|                 : null} |                           : null} | ||||||
| 
 | 
 | ||||||
|               <div style={{ marginTop: '20px', position: 'absolute', bottom: '10px' }}> |                         <div style={{ marginTop: '20px', position: 'absolute', bottom: '10px' }}> | ||||||
|                 <Button style={{ marginRight: '10px', height: '35px' }} variant='contained' disabled={this.props.activeStep === 0} onClick={() => this.props.tutorialStep(this.props.activeStep - 1)}>Zurück</Button> |                           <Button style={{ marginRight: '10px', height: '35px' }} variant='contained' disabled={this.props.activeStep === 0} onClick={() => this.props.tutorialStep(this.props.activeStep - 1)}>Zurück</Button> | ||||||
|                 <Button style={{ height: '35px' }} variant='contained' color='primary' disabled={this.props.activeStep === tutorial.steps.length - 1} onClick={() => this.props.tutorialStep(this.props.activeStep + 1)}>Weiter</Button> |                           <Button style={{ height: '35px' }} variant='contained' color='primary' disabled={this.props.activeStep === tutorial.steps.length - 1} onClick={() => this.props.tutorialStep(this.props.activeStep + 1)}>Weiter</Button> | ||||||
|               </div> |                         </div> | ||||||
|             </Card> |                       </Card> | ||||||
|           </div> |                     </div> | ||||||
|         </div> |                   </div> | ||||||
|  |               )})() | ||||||
|  |         } | ||||||
|  |       </div> | ||||||
|     ); |     ); | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Tutorial.propTypes = { | Tutorial.propTypes = { | ||||||
|   tutorialId: PropTypes.func.isRequired, |   getTutorial: PropTypes.func.isRequired, | ||||||
|  |   resetTutorial: PropTypes.func.isRequired, | ||||||
|  |   clearMessages: PropTypes.func.isRequired, | ||||||
|   tutorialStep: PropTypes.func.isRequired, |   tutorialStep: PropTypes.func.isRequired, | ||||||
|   workspaceName: PropTypes.func.isRequired, |   workspaceName: PropTypes.func.isRequired, | ||||||
|   currentTutorialId: PropTypes.number, |  | ||||||
|   status: PropTypes.array.isRequired, |   status: PropTypes.array.isRequired, | ||||||
|   change: PropTypes.number.isRequired, |   change: PropTypes.number.isRequired, | ||||||
|   activeStep: PropTypes.number.isRequired |   activeStep: PropTypes.number.isRequired, | ||||||
|  |   tutorial: PropTypes.object.isRequired, | ||||||
|  |   isLoading: PropTypes.bool.isRequired, | ||||||
|  |   message: PropTypes.object.isRequired | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const mapStateToProps = state => ({ | const mapStateToProps = state => ({ | ||||||
|   change: state.tutorial.change, |   change: state.tutorial.change, | ||||||
|   status: state.tutorial.status, |   status: state.tutorial.status, | ||||||
|   currentTutorialId: state.tutorial.currentId, |   activeStep: state.tutorial.activeStep, | ||||||
|   activeStep: state.tutorial.activeStep |   tutorial: state.tutorial.tutorial, | ||||||
|  |   isLoading: state.tutorial.progress, | ||||||
|  |   message: state.message | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| export default connect(mapStateToProps, { tutorialId, tutorialStep, workspaceName })(Tutorial); | export default connect(mapStateToProps, { getTutorial, resetTutorial, tutorialStep, clearMessages, workspaceName })(Tutorial); | ||||||
|  | |||||||
| @ -3,10 +3,12 @@ import workspaceReducer from './workspaceReducer'; | |||||||
| import tutorialReducer from './tutorialReducer'; | import tutorialReducer from './tutorialReducer'; | ||||||
| import tutorialBuilderReducer from './tutorialBuilderReducer'; | import tutorialBuilderReducer from './tutorialBuilderReducer'; | ||||||
| import generalReducer from './generalReducer'; | import generalReducer from './generalReducer'; | ||||||
|  | import messageReducer from './messageReducer'; | ||||||
| 
 | 
 | ||||||
| export default combineReducers({ | export default combineReducers({ | ||||||
|   workspace: workspaceReducer, |   workspace: workspaceReducer, | ||||||
|   tutorial: tutorialReducer, |   tutorial: tutorialReducer, | ||||||
|   builder: tutorialBuilderReducer, |   builder: tutorialBuilderReducer, | ||||||
|   general: generalReducer |   general: generalReducer, | ||||||
|  |   message: messageReducer | ||||||
| }); | }); | ||||||
|  | |||||||
							
								
								
									
										27
									
								
								src/reducers/messageReducer.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/reducers/messageReducer.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | |||||||
|  | import { GET_ERRORS, CLEAR_MESSAGES, GET_SUCCESS } from '../actions/types'; | ||||||
|  | 
 | ||||||
|  | const initialState = { | ||||||
|  |   msg: {}, | ||||||
|  |   status: null, | ||||||
|  |   id: null | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default function(state = initialState, action){ | ||||||
|  |   switch(action.type){ | ||||||
|  |     case GET_ERRORS: | ||||||
|  |     case GET_SUCCESS: | ||||||
|  |       return { | ||||||
|  |         msg: action.payload.msg, | ||||||
|  |         status: action.payload.status, | ||||||
|  |         id: action.payload.id | ||||||
|  |       }; | ||||||
|  |     case CLEAR_MESSAGES: | ||||||
|  |       return { | ||||||
|  |         msg: {}, | ||||||
|  |         status: null, | ||||||
|  |         id: null | ||||||
|  |       }; | ||||||
|  |     default: | ||||||
|  |       return state; | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -1,4 +1,4 @@ | |||||||
| import { TUTORIAL_SUCCESS, TUTORIAL_ERROR, TUTORIAL_CHANGE, TUTORIAL_XML, TUTORIAL_ID, TUTORIAL_STEP } from '../actions/types'; | import { TUTORIAL_PROGRESS, GET_TUTORIAL, TUTORIAL_SUCCESS, TUTORIAL_ERROR, TUTORIAL_CHANGE, TUTORIAL_XML, TUTORIAL_ID, TUTORIAL_STEP } from '../actions/types'; | ||||||
| 
 | 
 | ||||||
| import tutorials from '../data/tutorials'; | import tutorials from '../data/tutorials'; | ||||||
| 
 | 
 | ||||||
| @ -40,14 +40,26 @@ const initialStatus = () => { | |||||||
| 
 | 
 | ||||||
| const initialState = { | const initialState = { | ||||||
|   status: initialStatus(), |   status: initialStatus(), | ||||||
|   currentId: null, |   // currentId: null,
 | ||||||
|   currentIndex: null, |   currentIndex: null, | ||||||
|   activeStep: 0, |   activeStep: 0, | ||||||
|   change: 0 |   change: 0, | ||||||
|  |   tutorial: {}, | ||||||
|  |   progress: false | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export default function (state = initialState, action) { | export default function (state = initialState, action) { | ||||||
|   switch (action.type) { |   switch (action.type) { | ||||||
|  |     case TUTORIAL_PROGRESS: | ||||||
|  |       return { | ||||||
|  |         ...state, | ||||||
|  |         progress: !state.progress | ||||||
|  |       } | ||||||
|  |     case GET_TUTORIAL: | ||||||
|  |       return { | ||||||
|  |         ...state, | ||||||
|  |         tutorial: action.payload | ||||||
|  |       }; | ||||||
|     case TUTORIAL_SUCCESS: |     case TUTORIAL_SUCCESS: | ||||||
|     case TUTORIAL_ERROR: |     case TUTORIAL_ERROR: | ||||||
|     case TUTORIAL_XML: |     case TUTORIAL_XML: | ||||||
| @ -65,7 +77,7 @@ export default function (state = initialState, action) { | |||||||
|     case TUTORIAL_ID: |     case TUTORIAL_ID: | ||||||
|       return { |       return { | ||||||
|         ...state, |         ...state, | ||||||
|         currentId: action.payload, |         // currentId: action.payload,
 | ||||||
|         currentIndex: tutorials.findIndex(tutorial => tutorial.id === action.payload) |         currentIndex: tutorials.findIndex(tutorial => tutorial.id === action.payload) | ||||||
|       } |       } | ||||||
|     case TUTORIAL_STEP: |     case TUTORIAL_STEP: | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user