current tutorial id stored in redux store

This commit is contained in:
Delucse 2020-09-08 13:42:55 +02:00
parent c1d3962fb4
commit 7e0fbf1f75
9 changed files with 214 additions and 127 deletions

49
.idea/workspace.xml generated Normal file
View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="a119841b-a70a-4b0e-91b6-4da6cd81f169" name="Default Changelist" comment="">
<change beforePath="$PROJECT_DIR$/src/components/Tutorial/tutorials.json" beforeDir="false" />
</list>
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
</component>
<component name="SvnConfiguration">
<configuration />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="a119841b-a70a-4b0e-91b6-4da6cd81f169" name="Default Changelist" comment="" />
<created>1599559503505</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1599559503505</updated>
</task>
<servers />
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State />
</value>
</entry>
</map>
</option>
</component>
</project>

View File

@ -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) => { export const tutorialChange = () => (dispatch) => {
dispatch({ dispatch({
@ -15,3 +15,19 @@ export const tutorialCheck = (id, status) => (dispatch, getState) => {
}); });
dispatch(tutorialChange()); 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
});
};

View File

@ -10,3 +10,5 @@ export const CLEAR_STATS = 'CLEAR_STATS';
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';
export const TUTORIAL_XML = 'TUTORIAL_XML';
export const TUTORIAL_ID = 'TUTORIAL_ID';

View File

@ -9,8 +9,6 @@ import Compile from '../Compile';
import { tutorials } from './tutorials'; import { tutorials } from './tutorials';
import { withRouter } from 'react-router-dom';
import { withStyles } from '@material-ui/core/styles'; import { withStyles } from '@material-ui/core/styles';
import IconButton from '@material-ui/core/IconButton'; import IconButton from '@material-ui/core/IconButton';
import Tooltip from '@material-ui/core/Tooltip'; import Tooltip from '@material-ui/core/Tooltip';
@ -51,56 +49,61 @@ class SolutionCheck extends Component {
check = () => { check = () => {
const workspace = Blockly.getMainWorkspace(); const workspace = Blockly.getMainWorkspace();
var msg = tutorials[this.props.tutorial].test(workspace); var msg = tutorials[this.props.currentTutorialId].test(workspace);
this.props.tutorialCheck(this.props.tutorial, msg.type); this.props.tutorialCheck(this.props.currentTutorialId, msg.type);
this.setState({ msg, open: true }); this.setState({ msg, open: true });
} }
render() { render() {
return ( return (
tutorials[this.props.tutorial].test ? tutorials[this.props.currentTutorialId].test ?
<div> <div>
<Tooltip title='Lösung kontrollieren'> <Tooltip title='Lösung kontrollieren'>
<IconButton <IconButton
className={this.props.classes.compile} className={this.props.classes.compile}
style={{width: '40px', height: '40px', position: 'absolute', top: 8, right: 8, zIndex: 21 }} style={{width: '40px', height: '40px', position: 'absolute', top: 8, right: 8, zIndex: 21 }}
onClick={() => this.check()} onClick={() => this.check()}
> >
<FontAwesomeIcon icon={faPlay} size="xs"/> <FontAwesomeIcon icon={faPlay} size="xs"/>
</IconButton> </IconButton>
</Tooltip> </Tooltip>
<Dialog fullWidth maxWidth={'sm'} onClose={this.toggleDialog} open={this.state.open} style={{zIndex: 9999999}}> <Dialog fullWidth maxWidth={'sm'} onClose={this.toggleDialog} open={this.state.open} style={{zIndex: 9999999}}>
<DialogTitle>{this.state.msg.type === 'error' ? 'Fehler' : 'Erfolg'}</DialogTitle> <DialogTitle>{this.state.msg.type === 'error' ? 'Fehler' : 'Erfolg'}</DialogTitle>
<DialogContent dividers> <DialogContent dividers>
{this.state.msg.text} {this.state.msg.text}
{this.state.msg.type === 'success' ? {this.state.msg.type === 'success' ?
<div style={{marginTop: '20px', display: 'flex'}}> <div style={{marginTop: '20px', display: 'flex'}}>
<Compile /> <Compile />
<Button <Button
style={{marginLeft: '10px'}} style={{marginLeft: '10px'}}
variant="contained" variant="contained"
color="primary" color="primary"
onClick={() => {this.toggleDialog(); this.props.history.push(`/tutorial/${this.props.tutorial+2}`)}} onClick={() => {this.toggleDialog(); this.props.history.push(`/tutorial/${this.props.currentTutorialId+2}`)}}
> >
nächstes Tutorial nächstes Tutorial
</Button>
</div>
: null}
</DialogContent>
<DialogActions>
<Button onClick={this.toggleDialog} color="primary">
Schließen
</Button> </Button>
</div> </DialogActions>
: null} </Dialog>
</DialogContent> </div>
<DialogActions>
<Button onClick={this.toggleDialog} color="primary">
Schließen
</Button>
</DialogActions>
</Dialog>
</div>
: null : null
); );
}; };
} }
SolutionCheck.propTypes = { SolutionCheck.propTypes = {
tutorialCheck: PropTypes.func.isRequired tutorialCheck: PropTypes.func.isRequired,
currentTutorialId: PropTypes.number
}; };
export default connect(null, { tutorialCheck })(withRouter(withStyles(styles, {withTheme: true})(SolutionCheck))); const mapStateToProps = state => ({
currentTutorialId: state.tutorial.currentId
});
export default connect(mapStateToProps, { tutorialCheck })(withStyles(styles, {withTheme: true})(SolutionCheck));

View File

@ -49,39 +49,29 @@ const styles = (theme) => ({
class StepperHorizontal extends Component { class StepperHorizontal extends Component {
state={
tutorialId: Number(this.props.match.params.tutorialId),
}
componentDidUpdate(props, state){
if(state.tutorialId !== Number(this.props.match.params.tutorialId)){
this.setState({tutorialId: Number(this.props.match.params.tutorialId)})
}
}
render() { render() {
var tutorialId = this.state.tutorialId; var tutorialId = this.props.currentTutorialId;
var tutorialStatus = this.props.status[tutorialId-1].status === 'success' ? 'Success' : var tutorialStatus = this.props.status[tutorialId].status === 'success' ? 'Success' :
this.props.status[tutorialId-1].status === 'error' ? 'Error' : 'Other'; this.props.status[tutorialId].status === 'error' ? 'Error' : 'Other';
return ( return (
<div className={clsx(this.props.classes.stepper, this.props.classes['stepper'+tutorialStatus])}> <div className={clsx(this.props.classes.stepper, this.props.classes['stepper'+tutorialStatus])}>
<Button <Button
disabled={tutorialId-1 === 0} disabled={tutorialId === 0}
onClick={() => {this.props.history.push(`/tutorial/${tutorialId-1}`)}} onClick={() => {this.props.history.push(`/tutorial/${tutorialId}`)}}
> >
{'<'} {'<'}
</Button> </Button>
<Stepper activeStep={tutorialId} orientation="horizontal" <Stepper activeStep={tutorialId+1} orientation="horizontal"
style={{padding: 0}} classes={{root: this.props.classes.color}}> style={{padding: 0}} classes={{root: this.props.classes.color}}>
<Step expanded completed={false}> <Step expanded completed={false}>
<StepLabel icon={tutorialStatus !== 'Other' ? <div className={clsx(tutorialStatus === 'Error' ? this.props.classes.iconDivError: this.props.classes.iconDivSuccess)}><FontAwesomeIcon className={this.props.classes.icon} icon={tutorialStatus === 'Success' ? faCheck : faTimes}/></div> : ''}> <StepLabel icon={tutorialStatus !== 'Other' ? <div className={clsx(tutorialStatus === 'Error' ? this.props.classes.iconDivError: this.props.classes.iconDivSuccess)}><FontAwesomeIcon className={this.props.classes.icon} icon={tutorialStatus === 'Success' ? faCheck : faTimes}/></div> : ''}>
<h1 style={{margin: 0}}>{tutorials[tutorialId-1].title}</h1> <h1 style={{margin: 0}}>{tutorials[tutorialId].title}</h1>
</StepLabel> </StepLabel>
</Step> </Step>
</Stepper> </Stepper>
<Button <Button
disabled={tutorialId+1 > tutorials.length} disabled={tutorialId+2 > tutorials.length}
onClick={() => {this.props.history.push(`/tutorial/${tutorialId+1}`)}} onClick={() => {this.props.history.push(`/tutorial/${tutorialId+2}`)}}
> >
{'>'} {'>'}
</Button> </Button>
@ -93,11 +83,13 @@ 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
}; };
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
}); });
export default connect(mapStateToProps, null)(withRouter(withStyles(styles, {withTheme: true})(StepperHorizontal))); export default connect(mapStateToProps, null)(withRouter(withStyles(styles, {withTheme: true})(StepperHorizontal)));

View File

@ -24,7 +24,7 @@ const styles = (theme) => ({
}, },
stepIcon: { stepIcon: {
borderStyle: `solid`, borderStyle: `solid`,
borderWith: '2px', // borderWidth: '2px',
borderRadius: '50%', borderRadius: '50%',
width: '12px', width: '12px',
height: '12px', height: '12px',
@ -72,67 +72,69 @@ const styles = (theme) => ({
}, },
progressBackground: { progressBackground: {
backgroundColor: fade(theme.palette.primary.main, 0.2), backgroundColor: fade(theme.palette.primary.main, 0.2),
height: '100%' height: '100%',
borderRadius: '2px'
} }
}); });
class StepperVertical extends Component { class StepperVertical extends Component {
state={ constructor(props){
tutorialArray: Number(this.props.match.params.tutorialId) === 1 ? super(props);
tutorials.slice(Number(this.props.match.params.tutorialId)-1, Number(this.props.match.params.tutorialId)+4) this.state = {
: Number(this.props.match.params.tutorialId) === 2 ? tutorialArray: props.currentTutorialId === 0 ?
tutorials.slice(Number(this.props.match.params.tutorialId)-1-1, Number(this.props.match.params.tutorialId)+3) tutorials.slice(props.currentTutorialId, props.currentTutorialId+5)
: Number(this.props.match.params.tutorialId) === tutorials.length ? : props.currentTutorialId === 1 ?
tutorials.slice(Number(this.props.match.params.tutorialId)-4-1, Number(this.props.match.params.tutorialId)+4) tutorials.slice(props.currentTutorialId-1, props.currentTutorialId+4)
: Number(this.props.match.params.tutorialId) === tutorials.length-1 ? : props.currentTutorialId === tutorials.length-1 ?
tutorials.slice(Number(this.props.match.params.tutorialId)-3-1, Number(this.props.match.params.tutorialId)+3) tutorials.slice(props.currentTutorialId-4, props.currentTutorialId+5)
: tutorials.slice(Number(this.props.match.params.tutorialId)-2-1,Number(this.props.match.params.tutorialId)+2), : props.currentTutorialId === tutorials.length-2 ?
tutorialId: Number(this.props.match.params.tutorialId), tutorials.slice(props.currentTutorialId-3, props.currentTutorialId+4)
selectedVerticalTutorialId: Number(this.props.match.params.tutorialId) : tutorials.slice(props.currentTutorialId-2, props.currentTutorialId+3),
selectedVerticalTutorialId: props.currentTutorialId
};
} }
componentDidUpdate(props, state){ componentDidUpdate(props){
if(state.tutorialId !== Number(this.props.match.params.tutorialId)){ if(props.currentTutorialId !== this.props.currentTutorialId){
this.setState({ this.setState({
tutorialArray: Number(this.props.match.params.tutorialId) === 1 ? tutorialArray: props.currentTutorialId === 0 ?
tutorials.slice(Number(this.props.match.params.tutorialId)-1, Number(this.props.match.params.tutorialId)+4) tutorials.slice(props.currentTutorialId, props.currentTutorialId+5)
: Number(this.props.match.params.tutorialId) === 2 ? : props.currentTutorialId === 1 ?
tutorials.slice(Number(this.props.match.params.tutorialId)-1-1, Number(this.props.match.params.tutorialId)+3) tutorials.slice(props.currentTutorialId-1, props.currentTutorialId+4)
: Number(this.props.match.params.tutorialId) === tutorials.length ? : props.currentTutorialId === tutorials.length-1 ?
tutorials.slice(Number(this.props.match.params.tutorialId)-4-1, Number(this.props.match.params.tutorialId)+4) tutorials.slice(props.currentTutorialId-4, props.currentTutorialId+5)
: Number(this.props.match.params.tutorialId) === tutorials.length-1 ? : props.currentTutorialId === tutorials.length-2 ?
tutorials.slice(Number(this.props.match.params.tutorialId)-3-1, Number(this.props.match.params.tutorialId)+3) tutorials.slice(props.currentTutorialId-3, props.currentTutorialId+4)
: tutorials.slice(Number(this.props.match.params.tutorialId)-2-1,Number(this.props.match.params.tutorialId)+2), : tutorials.slice(props.currentTutorialId-2, props.currentTutorialId+3),
tutorialId: Number(this.props.match.params.tutorialId), selectedVerticalTutorialId: props.currentTutorialId
selectedVerticalTutorialId: Number(this.props.match.params.tutorialId) });
})
} }
} }
verticalStepper = (step) => { verticalStepper = (step) => {
var newTutorialId = this.state.selectedVerticalTutorialId + step; var newTutorialId = this.state.selectedVerticalTutorialId + step;
var tutorialArray = Number(newTutorialId) === 1 ? var tutorialArray = newTutorialId === 0 ?
tutorials.slice(newTutorialId-1, newTutorialId+4) tutorials.slice(newTutorialId, newTutorialId+5)
: newTutorialId === 2 ? : newTutorialId === 1 ?
tutorials.slice(newTutorialId-1-1, newTutorialId+3) tutorials.slice(newTutorialId-1, newTutorialId+4)
: newTutorialId === tutorials.length ? : newTutorialId === tutorials.length-1 ?
tutorials.slice(newTutorialId-4-1, newTutorialId+4) tutorials.slice(newTutorialId-4, newTutorialId+5)
: newTutorialId === tutorials.length-1 ? : newTutorialId === tutorials.length-2 ?
tutorials.slice(newTutorialId-3-1, newTutorialId+3) tutorials.slice(newTutorialId-3, newTutorialId+4)
: tutorials.slice(newTutorialId-2-1, newTutorialId+2); : tutorials.slice(newTutorialId-2, newTutorialId+3);
this.setState({ tutorialArray: tutorialArray, selectedVerticalTutorialId: newTutorialId }); this.setState({ tutorialArray: tutorialArray, selectedVerticalTutorialId: newTutorialId });
} }
render() { render() {
var tutorialId = this.state.tutorialId; var tutorialId = this.props.currentTutorialId;
var selectedVerticalTutorialId = this.state.selectedVerticalTutorialId; var selectedVerticalTutorialId = this.state.selectedVerticalTutorialId;
return ( return (
isWidthUp('sm', this.props.width) ? isWidthUp('sm', this.props.width) ?
<div style={{marginRight: '10px'}}> <div style={{marginRight: '10px'}}>
<Button <Button
style={{minWidth: '30px', margin: 'auto', minHeight: '25px', padding: '0', writingMode: 'vertical-rl'}} style={{minWidth: '30px', margin: 'auto', minHeight: '25px', padding: '0', writingMode: 'vertical-rl'}}
disabled={this.state.selectedVerticalTutorialId === 1} disabled={selectedVerticalTutorialId === 0}
onClick={() => {this.verticalStepper(-1)}} onClick={() => {this.verticalStepper(-1)}}
> >
{'<'} {'<'}
@ -141,22 +143,20 @@ class StepperVertical extends Component {
<div style={{position: 'relative'}}> <div style={{position: 'relative'}}>
<div <div
className={clsx(this.props.classes.progress, this.props.classes.progressForeground)} className={clsx(this.props.classes.progress, this.props.classes.progressForeground)}
style={{ zIndex: 1, borderRadius: `${selectedVerticalTutorialId/tutorials.length === 1 ? '2px' : '2px 2px 0 0'}`, height: `${(selectedVerticalTutorialId/tutorials.length)*100}%`}}> style={{ zIndex: 1, borderRadius: `${selectedVerticalTutorialId/(tutorials.length-1) === 1 ? '2px' : '2px 2px 0 0'}`, height: `${((selectedVerticalTutorialId+1)/tutorials.length)*100}%`}}>
</div> </div>
<div <div className={clsx(this.props.classes.progress, this.props.classes.progressBackground)}>
className={clsx(this.props.classes.progress, this.props.classes.progressBackground)}
style={{borderRadius: `${selectedVerticalTutorialId/tutorials.length === 1 ? '2px' : '2px 2px 0 0'}`}}>
</div> </div>
</div> </div>
<Stepper <Stepper
activeStep={tutorialId} activeStep={tutorialId+1}
orientation="vertical" orientation="vertical"
connector={<div style={{height: '10px'}}></div>} connector={<div style={{height: '10px'}}></div>}
classes={{root: this.props.classes.verticalStepper}} classes={{root: this.props.classes.verticalStepper}}
> >
{this.state.tutorialArray.map((tutorial, i) => { {this.state.tutorialArray.map((tutorial, i) => {
var index = this.state.tutorialArray.indexOf(tutorials[selectedVerticalTutorialId-1]); var index = this.state.tutorialArray.indexOf(tutorials[selectedVerticalTutorialId]);
var verticalTutorialId = i === index ? selectedVerticalTutorialId : selectedVerticalTutorialId - index + i; var verticalTutorialId = i === index ? selectedVerticalTutorialId+1 : selectedVerticalTutorialId+1 - index + i;
var tutorialStatus = this.props.status[verticalTutorialId-1].status === 'success' ? 'Success' : var tutorialStatus = this.props.status[verticalTutorialId-1].status === 'success' ? 'Success' :
this.props.status[verticalTutorialId-1].status === 'error' ? 'Error' : 'Other'; this.props.status[verticalTutorialId-1].status === 'error' ? 'Error' : 'Other';
return ( return (
@ -166,15 +166,16 @@ class StepperVertical extends Component {
<StepLabel <StepLabel
StepIconComponent={'div'} StepIconComponent={'div'}
classes={{ classes={{
root: tutorial === tutorials[selectedVerticalTutorialId-1] ? root: tutorial === tutorials[selectedVerticalTutorialId] ?
tutorial === tutorials[tutorialId-1] ? tutorial === tutorials[tutorialId] ?
clsx(this.props.classes.stepIcon, this.props.classes.stepIconLarge, this.props.classes['stepIcon'+tutorialStatus], this.props.classes['stepIconActive'+tutorialStatus]) clsx(this.props.classes.stepIcon, this.props.classes.stepIconLarge, this.props.classes['stepIcon'+tutorialStatus], this.props.classes['stepIconActive'+tutorialStatus])
: clsx(this.props.classes.stepIcon, this.props.classes.stepIconLarge, this.props.classes['stepIcon'+tutorialStatus]) : clsx(this.props.classes.stepIcon, this.props.classes.stepIconLarge, this.props.classes['stepIcon'+tutorialStatus])
: tutorial === tutorials[verticalTutorialId-2] || tutorial === tutorials[selectedVerticalTutorialId] ? : tutorial === tutorials[selectedVerticalTutorialId-1] || tutorial === tutorials[selectedVerticalTutorialId+1] ||
tutorial === tutorials[tutorialId-1] ? tutorial === tutorials[verticalTutorialId-2] ?
tutorial === tutorials[tutorialId] ?
clsx(this.props.classes.stepIcon, this.props.classes.stepIconMedium, this.props.classes['stepIcon'+tutorialStatus], this.props.classes['stepIconActive'+tutorialStatus]) clsx(this.props.classes.stepIcon, this.props.classes.stepIconMedium, this.props.classes['stepIcon'+tutorialStatus], this.props.classes['stepIconActive'+tutorialStatus])
: clsx(this.props.classes.stepIcon, this.props.classes.stepIconMedium, this.props.classes['stepIcon'+tutorialStatus]) : clsx(this.props.classes.stepIcon, this.props.classes.stepIconMedium, this.props.classes['stepIcon'+tutorialStatus])
: tutorial === tutorials[tutorialId-1] ? : tutorial === tutorials[tutorialId] ?
clsx(this.props.classes.stepIcon, this.props.classes['stepIcon'+tutorialStatus], this.props.classes['stepIconActive'+tutorialStatus]) clsx(this.props.classes.stepIcon, this.props.classes['stepIcon'+tutorialStatus], this.props.classes['stepIconActive'+tutorialStatus])
: clsx(this.props.classes.stepIcon, this.props.classes['stepIcon'+tutorialStatus]) : clsx(this.props.classes.stepIcon, this.props.classes['stepIcon'+tutorialStatus])
}} }}
@ -188,7 +189,7 @@ class StepperVertical extends Component {
</div> </div>
<Button <Button
style={{minWidth: '30px', minHeight: '25px', padding: '0', writingMode: 'vertical-rl'}} style={{minWidth: '30px', minHeight: '25px', padding: '0', writingMode: 'vertical-rl'}}
disabled={this.state.selectedVerticalTutorialId === tutorials.length} disabled={selectedVerticalTutorialId === tutorials.length-1}
onClick={() => {this.verticalStepper(1)}} onClick={() => {this.verticalStepper(1)}}
> >
{'>'} {'>'}
@ -203,11 +204,13 @@ 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
}; };
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
}); });
export default connect(mapStateToProps, null)(withRouter(withStyles(styles, {withTheme: true})(withWidth()(StepperVertical)))); export default connect(mapStateToProps, null)(withRouter(withStyles(styles, {withTheme: true})(withWidth()(StepperVertical))));

View File

@ -1,4 +1,7 @@
import React, { Component } from 'react'; 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 Breadcrumbs from '../Breadcrumbs';
import StepperHorizontal from './StepperHorizontal'; import StepperHorizontal from './StepperHorizontal';
@ -19,29 +22,32 @@ import Card from '@material-ui/core/Card';
class Tutorial extends Component { class Tutorial extends Component {
state={ state={
value: 'introduction', value: 'introduction'
tutorialId: Number(this.props.match.params.tutorialId) }
componentDidMount(){
this.props.tutorialId(Number(this.props.match.params.tutorialId)-1);
} }
componentDidUpdate(props, state){ componentDidUpdate(props, state){
if(state.tutorialId !== Number(this.props.match.params.tutorialId)){ if(props.currentTutorialId+1 !== Number(this.props.match.params.tutorialId)){
this.setState({ value: 'introduction', tutorialId: Number(this.props.match.params.tutorialId) }); this.props.tutorialId(Number(this.props.match.params.tutorialId)-1);
this.setState({ value: 'introduction' });
} }
} }
onChange = (e, value) => { onChange = (e, value) => {
console.log(value);
this.setState({ value: value }); this.setState({ value: value });
} }
render() { render() {
var tutorialId = this.state.tutorialId; var currentTutorialId = this.props.currentTutorialId;
return ( return (
!Number.isInteger(tutorialId) || tutorialId < 1 || tutorialId > tutorials.length ? !Number.isInteger(currentTutorialId) || currentTutorialId+1 < 1 || currentTutorialId+1 > tutorials.length ?
<NotFound button={{title: 'Zurück zur Tutorials-Übersicht', link: '/tutorial'}}/> <NotFound button={{title: 'Zurück zur Tutorials-Übersicht', link: '/tutorial'}}/>
: :
<div> <div>
<Breadcrumbs content={[{link: '/', title: 'Home'},{link: '/tutorial', title: 'Tutorial'}, {link: `/tutorial/${tutorialId}`, title: tutorials[tutorialId-1].title}]}/> <Breadcrumbs content={[{link: '/', title: 'Home'},{link: '/tutorial', title: 'Tutorial'}, {link: `/tutorial/${currentTutorialId+1}`, title: tutorials[currentTutorialId].title}]}/>
<StepperHorizontal /> <StepperHorizontal />
@ -67,7 +73,7 @@ class Tutorial extends Component {
{this.state.value === 'assessment' ? {this.state.value === 'assessment' ?
<Grid container spacing={2}> <Grid container spacing={2}>
<Grid item xs={12} md={6} lg={8} style={{ position: 'relative' }}> <Grid item xs={12} md={6} lg={8} style={{ position: 'relative' }}>
<SolutionCheck tutorial={tutorialId-1}/> <SolutionCheck />
<BlocklyWindow /> <BlocklyWindow />
</Grid> </Grid>
<Grid item xs={12} md={6} lg={4}> <Grid item xs={12} md={6} lg={4}>
@ -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));

View File

@ -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'; import { tutorials } from '../components/Tutorial/tutorials';
@ -6,6 +6,7 @@ const initialState = {
status: window.localStorage.getItem('tutorial') ? status: window.localStorage.getItem('tutorial') ?
JSON.parse(window.localStorage.getItem('tutorial')) JSON.parse(window.localStorage.getItem('tutorial'))
: new Array(tutorials.length).fill({}), : new Array(tutorials.length).fill({}),
currentId: null,
change: 0 change: 0
}; };
@ -13,6 +14,7 @@ export default function(state = initialState, action){
switch(action.type){ switch(action.type){
case TUTORIAL_SUCCESS: case TUTORIAL_SUCCESS:
case TUTORIAL_ERROR: case TUTORIAL_ERROR:
case TUTORIAL_XML:
// update locale storage - sync with redux store // update locale storage - sync with redux store
window.localStorage.setItem('tutorial', JSON.stringify(action.payload)); window.localStorage.setItem('tutorial', JSON.stringify(action.payload));
return { return {
@ -24,6 +26,11 @@ export default function(state = initialState, action){
...state, ...state,
change: state.change += 1 change: state.change += 1
} }
case TUTORIAL_ID:
return {
...state,
currentId: action.payload
}
default: default:
return state; return state;
} }

View File

@ -11,7 +11,7 @@ const store = createStore(
initialState, initialState,
compose( compose(
applyMiddleware(...middleware), applyMiddleware(...middleware),
// window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
) )
); );