From 7e0fbf1f75fa0790076156eb241c389baff7a0a4 Mon Sep 17 00:00:00 2001
From: Delucse <46593742+Delucse@users.noreply.github.com>
Date: Tue, 8 Sep 2020 13:42:55 +0200
Subject: [PATCH] current tutorial id stored in redux store
---
 .idea/workspace.xml                          |  49 +++++++++
 src/actions/tutorialActions.js               |  18 ++-
 src/actions/types.js                         |   2 +
 src/components/Tutorial/SolutionCheck.js     |  85 ++++++++-------
 src/components/Tutorial/StepperHorizontal.js |  32 ++----
 src/components/Tutorial/StepperVertical.js   | 109 ++++++++++---------
 src/components/Tutorial/Tutorial.js          |  35 ++++--
 src/reducers/tutorialReducer.js              |   9 +-
 src/store.js                                 |   2 +-
 9 files changed, 214 insertions(+), 127 deletions(-)
 create mode 100644 .idea/workspace.xml
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 0000000..fe7d374
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,49 @@
+
+
+  
+    
+      
+    
+    
+    
+    
+    
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+      
+      1599559503505
+      
+      
+      1599559503505
+    
+    
+  
+  
+    
+      
+    
+  
+
\ No newline at end of file
diff --git a/src/actions/tutorialActions.js b/src/actions/tutorialActions.js
index 1628154..5db9da3 100644
--- a/src/actions/tutorialActions.js
+++ b/src/actions/tutorialActions.js
@@ -1,4 +1,4 @@
-import { TUTORIAL_SUCCESS, TUTORIAL_ERROR, TUTORIAL_CHANGE } from './types';
+import { TUTORIAL_SUCCESS, TUTORIAL_ERROR, TUTORIAL_CHANGE, TUTORIAL_XML, TUTORIAL_ID } from './types';
 
 export const tutorialChange = () => (dispatch) => {
   dispatch({
@@ -15,3 +15,19 @@ export const tutorialCheck = (id, status) => (dispatch, getState) => {
   });
   dispatch(tutorialChange());
 };
+
+export const storeTutorialXml = (id) => (dispatch, getState) => {
+  var tutorialsStatus = getState().tutorial.status;
+  tutorialsStatus[id] = {...tutorialsStatus[id]};
+  dispatch({
+    type: TUTORIAL_XML,
+    payload: tutorialsStatus
+  });
+};
+
+export const tutorialId = (id) => (dispatch) => {
+  dispatch({
+    type: TUTORIAL_ID,
+    payload: id
+  });
+};
diff --git a/src/actions/types.js b/src/actions/types.js
index 28e5e33..11d24ac 100644
--- a/src/actions/types.js
+++ b/src/actions/types.js
@@ -10,3 +10,5 @@ export const CLEAR_STATS = 'CLEAR_STATS';
 export const TUTORIAL_SUCCESS = 'TUTORIAL_SUCCESS';
 export const TUTORIAL_ERROR = 'TUTORIAL_ERROR';
 export const TUTORIAL_CHANGE = 'TUTORIAL_CHANGE';
+export const TUTORIAL_XML = 'TUTORIAL_XML';
+export const TUTORIAL_ID = 'TUTORIAL_ID';
diff --git a/src/components/Tutorial/SolutionCheck.js b/src/components/Tutorial/SolutionCheck.js
index 01a9380..9ab5808 100644
--- a/src/components/Tutorial/SolutionCheck.js
+++ b/src/components/Tutorial/SolutionCheck.js
@@ -9,8 +9,6 @@ import Compile from '../Compile';
 
 import { tutorials } from './tutorials';
 
-import { withRouter } from 'react-router-dom';
-
 import { withStyles } from '@material-ui/core/styles';
 import IconButton from '@material-ui/core/IconButton';
 import Tooltip from '@material-ui/core/Tooltip';
@@ -51,56 +49,61 @@ class SolutionCheck extends Component {
 
   check = () => {
     const workspace = Blockly.getMainWorkspace();
-    var msg = tutorials[this.props.tutorial].test(workspace);
-    this.props.tutorialCheck(this.props.tutorial, msg.type);
+    var msg = tutorials[this.props.currentTutorialId].test(workspace);
+    this.props.tutorialCheck(this.props.currentTutorialId, msg.type);
     this.setState({ msg, open: true });
   }
 
   render() {
     return (
-      tutorials[this.props.tutorial].test ?
-
-        
-           this.check()}
-          >
-            
-          
-        
-        
+        
          {this.props.history.push(`/tutorial/${tutorialId-1}`)}}
+          disabled={tutorialId === 0}
+          onClick={() => {this.props.history.push(`/tutorial/${tutorialId}`)}}
         >
           {'<'}
         
-        
           
             
 : ''}>
-              {tutorials[tutorialId-1].title}
+              {tutorials[tutorialId].title}
             
           
         
          tutorials.length}
-          onClick={() => {this.props.history.push(`/tutorial/${tutorialId+1}`)}}
+          disabled={tutorialId+2 > tutorials.length}
+          onClick={() => {this.props.history.push(`/tutorial/${tutorialId+2}`)}}
         >
           {'>'}
         
@@ -93,11 +83,13 @@ class StepperHorizontal extends Component {
 StepperHorizontal.propTypes = {
   status: PropTypes.array.isRequired,
   change: PropTypes.number.isRequired,
+  currentTutorialId: PropTypes.number.isRequired
 };
 
 const mapStateToProps = state => ({
   change: state.tutorial.change,
-  status: state.tutorial.status
+  status: state.tutorial.status,
+  currentTutorialId: state.tutorial.currentId
 });
 
 export default connect(mapStateToProps, null)(withRouter(withStyles(styles, {withTheme: true})(StepperHorizontal)));
diff --git a/src/components/Tutorial/StepperVertical.js b/src/components/Tutorial/StepperVertical.js
index 48ea972..333cd0b 100644
--- a/src/components/Tutorial/StepperVertical.js
+++ b/src/components/Tutorial/StepperVertical.js
@@ -24,7 +24,7 @@ const styles = (theme) => ({
   },
   stepIcon: {
     borderStyle: `solid`,
-    borderWith: '2px',
+    // borderWidth: '2px',
     borderRadius: '50%',
     width: '12px',
     height: '12px',
@@ -72,67 +72,69 @@ const styles = (theme) => ({
   },
   progressBackground: {
     backgroundColor: fade(theme.palette.primary.main, 0.2),
-    height: '100%'
+    height: '100%',
+    borderRadius: '2px'
   }
 });
 
 class StepperVertical extends Component {
 
-  state={
-    tutorialArray: Number(this.props.match.params.tutorialId) === 1 ?
-                    tutorials.slice(Number(this.props.match.params.tutorialId)-1, Number(this.props.match.params.tutorialId)+4)
-                    : Number(this.props.match.params.tutorialId) === 2 ?
-                        tutorials.slice(Number(this.props.match.params.tutorialId)-1-1, Number(this.props.match.params.tutorialId)+3)
-                        : Number(this.props.match.params.tutorialId) === tutorials.length ?
-                              tutorials.slice(Number(this.props.match.params.tutorialId)-4-1, Number(this.props.match.params.tutorialId)+4)
-                            : Number(this.props.match.params.tutorialId) === tutorials.length-1 ?
-                                  tutorials.slice(Number(this.props.match.params.tutorialId)-3-1, Number(this.props.match.params.tutorialId)+3)
-                                : tutorials.slice(Number(this.props.match.params.tutorialId)-2-1,Number(this.props.match.params.tutorialId)+2),
-    tutorialId: Number(this.props.match.params.tutorialId),
-    selectedVerticalTutorialId: Number(this.props.match.params.tutorialId)
+  constructor(props){
+    super(props);
+    this.state = {
+      tutorialArray: props.currentTutorialId === 0 ?
+                      tutorials.slice(props.currentTutorialId, props.currentTutorialId+5)
+                      : props.currentTutorialId === 1 ?
+                          tutorials.slice(props.currentTutorialId-1, props.currentTutorialId+4)
+                          : props.currentTutorialId === tutorials.length-1 ?
+                                tutorials.slice(props.currentTutorialId-4, props.currentTutorialId+5)
+                              : props.currentTutorialId === tutorials.length-2 ?
+                                    tutorials.slice(props.currentTutorialId-3, props.currentTutorialId+4)
+                                  : tutorials.slice(props.currentTutorialId-2, props.currentTutorialId+3),
+      selectedVerticalTutorialId: props.currentTutorialId
+    };
   }
 
-  componentDidUpdate(props, state){
-    if(state.tutorialId !== Number(this.props.match.params.tutorialId)){
+  componentDidUpdate(props){
+    if(props.currentTutorialId !== this.props.currentTutorialId){
       this.setState({
-        tutorialArray: Number(this.props.match.params.tutorialId) === 1 ?
-                        tutorials.slice(Number(this.props.match.params.tutorialId)-1, Number(this.props.match.params.tutorialId)+4)
-                        : Number(this.props.match.params.tutorialId) === 2 ?
-                            tutorials.slice(Number(this.props.match.params.tutorialId)-1-1, Number(this.props.match.params.tutorialId)+3)
-                            : Number(this.props.match.params.tutorialId) === tutorials.length ?
-                                  tutorials.slice(Number(this.props.match.params.tutorialId)-4-1, Number(this.props.match.params.tutorialId)+4)
-                                : Number(this.props.match.params.tutorialId) === tutorials.length-1 ?
-                                      tutorials.slice(Number(this.props.match.params.tutorialId)-3-1, Number(this.props.match.params.tutorialId)+3)
-                                    : tutorials.slice(Number(this.props.match.params.tutorialId)-2-1,Number(this.props.match.params.tutorialId)+2),
-        tutorialId: Number(this.props.match.params.tutorialId),
-        selectedVerticalTutorialId: Number(this.props.match.params.tutorialId)
-      })
+        tutorialArray: props.currentTutorialId === 0 ?
+                        tutorials.slice(props.currentTutorialId, props.currentTutorialId+5)
+                        : props.currentTutorialId === 1 ?
+                            tutorials.slice(props.currentTutorialId-1, props.currentTutorialId+4)
+                            : props.currentTutorialId === tutorials.length-1 ?
+                                  tutorials.slice(props.currentTutorialId-4, props.currentTutorialId+5)
+                                : props.currentTutorialId === tutorials.length-2 ?
+                                      tutorials.slice(props.currentTutorialId-3, props.currentTutorialId+4)
+                                    : tutorials.slice(props.currentTutorialId-2, props.currentTutorialId+3),
+        selectedVerticalTutorialId: props.currentTutorialId
+      });
     }
   }
 
   verticalStepper = (step) => {
     var newTutorialId = this.state.selectedVerticalTutorialId + step;
-    var tutorialArray = Number(newTutorialId) === 1 ?
-                          tutorials.slice(newTutorialId-1, newTutorialId+4)
-                          : newTutorialId === 2 ?
-                                tutorials.slice(newTutorialId-1-1, newTutorialId+3)
-                              : newTutorialId === tutorials.length ?
-                                    tutorials.slice(newTutorialId-4-1, newTutorialId+4)
-                                  : newTutorialId === tutorials.length-1 ?
-                                        tutorials.slice(newTutorialId-3-1, newTutorialId+3)
-                                      : tutorials.slice(newTutorialId-2-1, newTutorialId+2);
+    var tutorialArray = newTutorialId === 0 ?
+                          tutorials.slice(newTutorialId, newTutorialId+5)
+                          : newTutorialId === 1 ?
+                                tutorials.slice(newTutorialId-1, newTutorialId+4)
+                              : newTutorialId === tutorials.length-1 ?
+                                    tutorials.slice(newTutorialId-4, newTutorialId+5)
+                                  : newTutorialId === tutorials.length-2 ?
+                                        tutorials.slice(newTutorialId-3, newTutorialId+4)
+                                      : tutorials.slice(newTutorialId-2, newTutorialId+3);
     this.setState({ tutorialArray: tutorialArray, selectedVerticalTutorialId: newTutorialId });
   }
 
   render() {
-    var tutorialId = this.state.tutorialId;
+    var tutorialId = this.props.currentTutorialId;
     var selectedVerticalTutorialId = this.state.selectedVerticalTutorialId;
     return (
       isWidthUp('sm', this.props.width) ?
         
              {this.verticalStepper(-1)}}
             >
               {'<'}
@@ -141,22 +143,20 @@ class StepperVertical extends Component {
               
                 
+                  style={{ zIndex: 1, borderRadius: `${selectedVerticalTutorialId/(tutorials.length-1) === 1 ? '2px' : '2px 2px 0 0'}`, height: `${((selectedVerticalTutorialId+1)/tutorials.length)*100}%`}}>
                 
-                
                }
                 classes={{root: this.props.classes.verticalStepper}}
               >
                 {this.state.tutorialArray.map((tutorial, i) => {
-                  var index = this.state.tutorialArray.indexOf(tutorials[selectedVerticalTutorialId-1]);
-                  var verticalTutorialId = i === index ? selectedVerticalTutorialId : selectedVerticalTutorialId - index + i;
+                  var index = this.state.tutorialArray.indexOf(tutorials[selectedVerticalTutorialId]);
+                  var verticalTutorialId = i === index ? selectedVerticalTutorialId+1 : selectedVerticalTutorialId+1 - index + i;
                   var tutorialStatus = this.props.status[verticalTutorialId-1].status === 'success' ? 'Success' :
                                         this.props.status[verticalTutorialId-1].status === 'error' ? 'Error' : 'Other';
                   return (
@@ -166,15 +166,16 @@ class StepperVertical extends Component {
                           
              {this.verticalStepper(1)}}
             >
               {'>'}
@@ -203,11 +204,13 @@ class StepperVertical extends Component {
 StepperVertical.propTypes = {
   status: PropTypes.array.isRequired,
   change: PropTypes.number.isRequired,
+  currentTutorialId: PropTypes.number.isRequired
 };
 
 const mapStateToProps = state => ({
   change: state.tutorial.change,
-  status: state.tutorial.status
+  status: state.tutorial.status,
+  currentTutorialId: state.tutorial.currentId
 });
 
 export default connect(mapStateToProps, null)(withRouter(withStyles(styles, {withTheme: true})(withWidth()(StepperVertical))));
diff --git a/src/components/Tutorial/Tutorial.js b/src/components/Tutorial/Tutorial.js
index d3fb08b..cae2bc7 100644
--- a/src/components/Tutorial/Tutorial.js
+++ b/src/components/Tutorial/Tutorial.js
@@ -1,4 +1,7 @@
 import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import { connect } from 'react-redux';
+import { tutorialId } from '../../actions/tutorialActions';
 
 import Breadcrumbs from '../Breadcrumbs';
 import StepperHorizontal from './StepperHorizontal';
@@ -19,29 +22,32 @@ import Card from '@material-ui/core/Card';
 class Tutorial extends Component {
 
   state={
-    value: 'introduction',
-    tutorialId: Number(this.props.match.params.tutorialId)
+    value: 'introduction'
+  }
+
+  componentDidMount(){
+    this.props.tutorialId(Number(this.props.match.params.tutorialId)-1);
   }
 
   componentDidUpdate(props, state){
-    if(state.tutorialId !== Number(this.props.match.params.tutorialId)){
-      this.setState({ value: 'introduction', tutorialId: Number(this.props.match.params.tutorialId) });
+    if(props.currentTutorialId+1 !== Number(this.props.match.params.tutorialId)){
+      this.props.tutorialId(Number(this.props.match.params.tutorialId)-1);
+      this.setState({ value: 'introduction' });
     }
   }
 
   onChange = (e, value) => {
-    console.log(value);
     this.setState({ value: value });
   }
 
   render() {
-    var tutorialId = this.state.tutorialId;
+    var currentTutorialId = this.props.currentTutorialId;
     return (
-      !Number.isInteger(tutorialId) || tutorialId < 1 || tutorialId > tutorials.length ?
+      !Number.isInteger(currentTutorialId) || currentTutorialId+1 < 1 || currentTutorialId+1 > tutorials.length ?
         
       :
         
-          
+          
 
           
 
@@ -67,7 +73,7 @@ class Tutorial extends Component {
                 {this.state.value === 'assessment' ?
                   
                     
-                      
+                      
                       
                     
                     
@@ -88,4 +94,13 @@ class Tutorial extends Component {
   };
 }
 
-export default withWidth()(Tutorial);
+Tutorial.propTypes = {
+  tutorialId: PropTypes.func.isRequired,
+  currentTutorialId: PropTypes.number.isRequired
+};
+
+const mapStateToProps = state => ({
+  currentTutorialId: state.tutorial.currentId
+});
+
+export default connect(mapStateToProps, { tutorialId })(withWidth()(Tutorial));
diff --git a/src/reducers/tutorialReducer.js b/src/reducers/tutorialReducer.js
index 7a9e691..1a9e1fc 100644
--- a/src/reducers/tutorialReducer.js
+++ b/src/reducers/tutorialReducer.js
@@ -1,4 +1,4 @@
-import { TUTORIAL_SUCCESS, TUTORIAL_ERROR, TUTORIAL_CHANGE } from '../actions/types';
+import { TUTORIAL_SUCCESS, TUTORIAL_ERROR, TUTORIAL_CHANGE, TUTORIAL_XML, TUTORIAL_ID } from '../actions/types';
 
 import { tutorials } from '../components/Tutorial/tutorials';
 
@@ -6,6 +6,7 @@ const initialState = {
   status: window.localStorage.getItem('tutorial') ?
             JSON.parse(window.localStorage.getItem('tutorial'))
           : new Array(tutorials.length).fill({}),
+  currentId: null,
   change: 0
 };
 
@@ -13,6 +14,7 @@ export default function(state = initialState, action){
   switch(action.type){
     case TUTORIAL_SUCCESS:
     case TUTORIAL_ERROR:
+    case TUTORIAL_XML:
       // update locale storage - sync with redux store
       window.localStorage.setItem('tutorial', JSON.stringify(action.payload));
       return {
@@ -24,6 +26,11 @@ export default function(state = initialState, action){
         ...state,
         change: state.change += 1
       }
+    case TUTORIAL_ID:
+      return {
+        ...state,
+        currentId: action.payload
+      }
     default:
       return state;
   }
diff --git a/src/store.js b/src/store.js
index bf6460e..bd28ae1 100644
--- a/src/store.js
+++ b/src/store.js
@@ -11,7 +11,7 @@ const store = createStore(
   initialState,
   compose(
     applyMiddleware(...middleware),
-    // window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
+    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
   )
 );