From b8a2f87321f1495770cfbd1f9ec2779abe923561 Mon Sep 17 00:00:00 2001 From: Delucse <46593742+Delucse@users.noreply.github.com> Date: Fri, 27 Nov 2020 09:30:42 +0100 Subject: [PATCH] get all tutorials about the API --- src/actions/tutorialActions.js | 44 +++++++++++-------- src/actions/types.js | 1 + src/components/Gallery/GalleryHome.js | 3 -- src/components/Tutorial/Assessment.js | 8 +--- .../Tutorial/Builder/Requirements.js | 33 +++++++++++--- src/components/Tutorial/Instruction.js | 11 +---- src/components/Tutorial/Requirement.js | 8 ++-- src/components/Tutorial/SolutionCheck.js | 9 ++-- src/components/Tutorial/StepperHorizontal.js | 6 +-- src/components/Tutorial/StepperVertical.js | 6 +-- src/components/Tutorial/Tutorial.js | 8 ++-- src/components/Tutorial/TutorialHome.js | 40 ++++++++++++++--- src/reducers/tutorialReducer.js | 15 ++++--- 13 files changed, 116 insertions(+), 76 deletions(-) diff --git a/src/actions/tutorialActions.js b/src/actions/tutorialActions.js index 10013e0..3443f07 100644 --- a/src/actions/tutorialActions.js +++ b/src/actions/tutorialActions.js @@ -1,10 +1,8 @@ -import { TUTORIAL_PROGRESS, GET_TUTORIAL, TUTORIAL_SUCCESS, TUTORIAL_ERROR, TUTORIAL_CHANGE, TUTORIAL_XML, TUTORIAL_ID, TUTORIAL_STEP } from './types'; +import { TUTORIAL_PROGRESS, GET_TUTORIAL, GET_TUTORIALS, TUTORIAL_SUCCESS, TUTORIAL_ERROR, TUTORIAL_CHANGE, TUTORIAL_XML, TUTORIAL_ID, TUTORIAL_STEP } from './types'; 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}`) @@ -23,10 +21,28 @@ export const getTutorial = (id) => (dispatch) => { }); }; +export const getTutorials = () => (dispatch) => { + dispatch({type: TUTORIAL_PROGRESS}); + axios.get(`https://api.blockly.sensebox.de/tutorial`) + .then(res => { + dispatch({type: TUTORIAL_PROGRESS}); + dispatch({ + type: GET_TUTORIALS, + payload: res.data + }); + }) + .catch(err => { + dispatch({type: TUTORIAL_PROGRESS}); + if(err.response){ + dispatch(returnErrors(err.response.data.message, err.response.status, 'GET_TUTORIALS_FAIL')); + } + }); +}; + export const resetTutorial = () => (dispatch) => { dispatch({ - type: GET_TUTORIAL, - payload: {} + type: GET_TUTORIALS, + payload: [] }); }; @@ -38,7 +54,7 @@ export const tutorialChange = () => (dispatch) => { export const tutorialCheck = (status, step) => (dispatch, getState) => { var tutorialsStatus = getState().tutorial.status; - var id = getState().tutorial.tutorial.id; + var id = getState().tutorial.tutorials[0].id; var tutorialsStatusIndex = tutorialsStatus.findIndex(tutorialStatus => tutorialStatus.id === id); var tasksIndex = tutorialsStatus[tutorialsStatusIndex].tasks.findIndex(task => task.id === step.id); tutorialsStatus[tutorialsStatusIndex].tasks[tasksIndex] = { @@ -53,11 +69,11 @@ export const tutorialCheck = (status, step) => (dispatch, getState) => { }; export const storeTutorialXml = (code) => (dispatch, getState) => { - var tutorial = getState().tutorial.tutorial; - var id = tutorial.id; - if (id !== null) { + var tutorial = getState().tutorial.tutorials[0]; + if (tutorial) { + var id = tutorial.id; var activeStep = getState().tutorial.activeStep; - var steps = tutorial.steps;//tutorials.filter(tutorial => tutorial.id === id)[0].steps; + var steps = tutorial.steps; if (steps && steps[activeStep].type === 'task') { var tutorialsStatus = getState().tutorial.status; var tutorialsStatusIndex = tutorialsStatus.findIndex(tutorialStatus => tutorialStatus.id === id); @@ -74,14 +90,6 @@ export const storeTutorialXml = (code) => (dispatch, getState) => { } }; - -// export const tutorialId = (id) => (dispatch) => { -// dispatch({ -// type: TUTORIAL_ID, -// payload: id -// }); -// }; - export const tutorialStep = (step) => (dispatch) => { dispatch({ type: TUTORIAL_STEP, diff --git a/src/actions/types.js b/src/actions/types.js index 15ca8c1..800b868 100644 --- a/src/actions/types.js +++ b/src/actions/types.js @@ -9,6 +9,7 @@ export const NAME = 'NAME'; export const TUTORIAL_PROGRESS = 'TUTORIAL_PROGRESS'; export const GET_TUTORIAL = 'GET_TUTORIAL'; +export const GET_TUTORIALS = 'GET_TUTORIALS'; export const TUTORIAL_SUCCESS = 'TUTORIAL_SUCCESS'; export const TUTORIAL_ERROR = 'TUTORIAL_ERROR'; export const TUTORIAL_CHANGE = 'TUTORIAL_CHANGE'; diff --git a/src/components/Gallery/GalleryHome.js b/src/components/Gallery/GalleryHome.js index 630681b..6e6772a 100644 --- a/src/components/Gallery/GalleryHome.js +++ b/src/components/Gallery/GalleryHome.js @@ -6,9 +6,6 @@ import clsx from 'clsx'; import Breadcrumbs from '../Breadcrumbs'; -// import gallery from './gallery.json'; -// import tutorials from '../../data/tutorials.json'; - import { Link } from 'react-router-dom'; import { fade } from '@material-ui/core/styles/colorManipulator'; diff --git a/src/components/Tutorial/Assessment.js b/src/components/Tutorial/Assessment.js index 2729774..3f62941 100644 --- a/src/components/Tutorial/Assessment.js +++ b/src/components/Tutorial/Assessment.js @@ -15,19 +15,17 @@ import Typography from '@material-ui/core/Typography'; class Assessment extends Component { componentDidMount() { - // alert(this.props.name); this.props.workspaceName(this.props.name); } componentDidUpdate(props) { if (props.name !== this.props.name) { - // alert(this.props.name); this.props.workspaceName(this.props.name); } } render() { - var tutorialId = this.props.tutorial.id //currentTutorialId; + var tutorialId = this.props.tutorial.id; var currentTask = this.props.step; var status = this.props.status.filter(status => status.id === tutorialId)[0]; var taskIndex = status.tasks.findIndex(task => task.id === currentTask.id); @@ -61,7 +59,6 @@ class Assessment extends Component { } Assessment.propTypes = { - // currentTutorialId: PropTypes.number, status: PropTypes.array.isRequired, change: PropTypes.number.isRequired, workspaceName: PropTypes.func.isRequired, @@ -71,8 +68,7 @@ Assessment.propTypes = { const mapStateToProps = state => ({ change: state.tutorial.change, status: state.tutorial.status, - tutorial: state.tutorial.tutorial - // currentTutorialId: state.tutorial.currentId + tutorial: state.tutorial.tutorials[0] }); export default connect(mapStateToProps, { workspaceName })(withWidth()(Assessment)); diff --git a/src/components/Tutorial/Builder/Requirements.js b/src/components/Tutorial/Builder/Requirements.js index 8be6bf4..ede201a 100644 --- a/src/components/Tutorial/Builder/Requirements.js +++ b/src/components/Tutorial/Builder/Requirements.js @@ -2,8 +2,8 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { changeContent } from '../../../actions/tutorialBuilderActions'; - -import tutorials from '../../../data/tutorials'; +import { getTutorials, resetTutorial } from '../../../actions/tutorialActions'; +import { clearMessages } from '../../../actions/messageActions'; import FormGroup from '@material-ui/core/FormGroup'; import Checkbox from '@material-ui/core/Checkbox'; @@ -14,6 +14,24 @@ import FormControl from '@material-ui/core/FormControl'; class Requirements extends Component { + componentDidMount() { + this.props.getTutorials(); + } + + componentDidUpdate(props, state) { + if(this.props.message.id === 'GET_TUTORIALS_FAIL'){ + alert(this.props.message.msg); + this.props.clearMessages(); + } + } + + componentWillUnmount() { + this.props.resetTutorial(); + if(this.props.message.msg){ + this.props.clearMessages(); + } + } + onChange = (e) => { var requirements = this.props.value; var value = parseInt(e.target.value) @@ -32,7 +50,7 @@ class Requirements extends Component { Voraussetzungen Beachte, dass die Reihenfolge des Anhakens maßgebend ist. - {tutorials.map((tutorial, i) => + {this.props.tutorials.map((tutorial, i) => ({ - change: state.builder.change + change: state.builder.change, + tutorials: state.tutorial.tutorials, + message: state.message }); -export default connect(mapStateToProps, { changeContent })(Requirements); +export default connect(mapStateToProps, { changeContent, getTutorials, resetTutorial, clearMessages })(Requirements); diff --git a/src/components/Tutorial/Instruction.js b/src/components/Tutorial/Instruction.js index fb82d8d..d0ecf02 100644 --- a/src/components/Tutorial/Instruction.js +++ b/src/components/Tutorial/Instruction.js @@ -1,6 +1,4 @@ import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import { connect } from 'react-redux'; import Hardware from './Hardware'; import Requirement from './Requirement'; @@ -55,12 +53,5 @@ class Instruction extends Component { }; } -Instruction.propTypes = { - // currentTutorialId: PropTypes.number, -}; -const mapStateToProps = state => ({ - // currentTutorialId: state.tutorial.currentId -}); - -export default connect(mapStateToProps, null)(Instruction); +export default Instruction; diff --git a/src/components/Tutorial/Requirement.js b/src/components/Tutorial/Requirement.js index 1ebd342..97e620c 100644 --- a/src/components/Tutorial/Requirement.js +++ b/src/components/Tutorial/Requirement.js @@ -74,16 +74,16 @@ class Requirement extends Component { var success = status.tasks.filter(task => task.type === 'success').length / tasks.length var tutorialStatus = success === 1 ? 'Success' : error ? 'Error' : 'Other'; return ( - +
{error || success === 1 ? - - : } + + : } {success < 1 && !error ? - + : null} diff --git a/src/components/Tutorial/SolutionCheck.js b/src/components/Tutorial/SolutionCheck.js index 08bec49..37cafa7 100644 --- a/src/components/Tutorial/SolutionCheck.js +++ b/src/components/Tutorial/SolutionCheck.js @@ -8,7 +8,6 @@ import { withRouter } from 'react-router-dom'; import Compile from '../Compile'; import Dialog from '../Dialog'; -// import tutorials from '../../data/tutorials'; import { checkXml } from '../../helpers/compareXml'; import { withStyles } from '@material-ui/core/styles'; @@ -47,7 +46,7 @@ class SolutionCheck extends Component { } check = () => { - const tutorial = this.props.tutorial //tutorials.filter(tutorial => tutorial.id === this.props.currentTutorialId)[0]; + const tutorial = this.props.tutorial; const step = tutorial.steps[this.props.activeStep]; var msg = checkXml(step.xml, this.props.xml); this.props.tutorialCheck(msg.type, step); @@ -55,7 +54,7 @@ class SolutionCheck extends Component { } render() { - const steps = this.props.tutorial.steps //tutorials.filter(tutorial => tutorial.id === this.props.currentTutorialId)[0].steps; + const steps = this.props.tutorial.steps; return (
@@ -114,17 +113,15 @@ class SolutionCheck extends Component { SolutionCheck.propTypes = { tutorialCheck: PropTypes.func.isRequired, tutorialStep: PropTypes.func.isRequired, - // currentTutorialId: PropTypes.number, activeStep: PropTypes.number.isRequired, xml: PropTypes.string.isRequired, tutorial: PropTypes.object.isRequired }; const mapStateToProps = state => ({ - // currentTutorialId: state.tutorial.currentId, activeStep: state.tutorial.activeStep, xml: state.workspace.code.xml, - tutorial: state.tutorial.tutorial + tutorial: state.tutorial.tutorials[0] }); export default connect(mapStateToProps, { tutorialCheck, tutorialStep })(withStyles(styles, { withTheme: true })(withRouter(SolutionCheck))); diff --git a/src/components/Tutorial/StepperHorizontal.js b/src/components/Tutorial/StepperHorizontal.js index f100ffb..89b7ccd 100644 --- a/src/components/Tutorial/StepperHorizontal.js +++ b/src/components/Tutorial/StepperHorizontal.js @@ -50,7 +50,7 @@ const styles = (theme) => ({ class StepperHorizontal extends Component { render() { - var tutorialId = this.props.tutorial.id //this.props.currentTutorialId; + var tutorialId = this.props.tutorial.id; var tutorialIndex = this.props.currentTutorialIndex; var status = this.props.status.filter(status => status.id === tutorialId)[0]; var tasks = status.tasks; @@ -96,7 +96,6 @@ class StepperHorizontal extends Component { StepperHorizontal.propTypes = { status: PropTypes.array.isRequired, change: PropTypes.number.isRequired, - // currentTutorialId: PropTypes.number.isRequired, currentTutorialIndex: PropTypes.number.isRequired, tutorial: PropTypes.object.isRequired }; @@ -104,9 +103,8 @@ StepperHorizontal.propTypes = { const mapStateToProps = state => ({ change: state.tutorial.change, status: state.tutorial.status, - // currentTutorialId: state.tutorial.currentId, currentTutorialIndex: state.tutorial.currentIndex, - tutorial: state.tutorial.tutorial + tutorial: state.tutorial.tutorials[0] }); 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 81e81a6..1535e20 100644 --- a/src/components/Tutorial/StepperVertical.js +++ b/src/components/Tutorial/StepperVertical.js @@ -69,7 +69,7 @@ class StepperVertical extends Component { render() { var steps = this.props.steps; var activeStep = this.props.activeStep; - var tutorialStatus = this.props.status.filter(status => status.id === this.props.tutorial.id/*currentTutorialId*/)[0]; + var tutorialStatus = this.props.status.filter(status => status.id === this.props.tutorial.id)[0]; return (
({ change: state.tutorial.change, status: state.tutorial.status, - // currentTutorialId: state.tutorial.currentId, activeStep: state.tutorial.activeStep, - tutorial: state.tutorial.tutorial + tutorial: state.tutorial.tutorials[0] }); export default connect(mapStateToProps, { tutorialStep })(withRouter(withStyles(styles, {withTheme: true})(StepperVertical))); diff --git a/src/components/Tutorial/Tutorial.js b/src/components/Tutorial/Tutorial.js index bb9f097..81440d3 100644 --- a/src/components/Tutorial/Tutorial.js +++ b/src/components/Tutorial/Tutorial.js @@ -14,7 +14,6 @@ import NotFound from '../NotFound'; import { detectWhitespacesAndReturnReadableResult } from '../../helpers/whitespace'; -// import tutorials from '../../data/tutorials'; import Card from '@material-ui/core/Card'; import Button from '@material-ui/core/Button'; @@ -28,7 +27,7 @@ class Tutorial extends Component { } componentDidUpdate(props, state) { - if (props.tutorial.id && !props.isLoading && Number(props.tutorial.id) !== Number(this.props.match.params.tutorialId)) { + if (props.tutorial && props.tutorial.id && !props.isLoading && Number(props.tutorial.id) !== Number(this.props.match.params.tutorialId)) { this.props.getTutorial(this.props.match.params.tutorialId); // this.props.tutorialId(Number(this.props.match.params.tutorialId)); } @@ -47,10 +46,11 @@ class Tutorial extends Component { } render() { + console.log(this.props.tutorial); return (
{this.props.isLoading ? : - Object.keys(this.props.tutorial).length === 0 ? + !this.props.tutorial ? : (() => { var tutorial = this.props.tutorial; var steps = this.props.tutorial.steps; @@ -104,7 +104,7 @@ const mapStateToProps = state => ({ change: state.tutorial.change, status: state.tutorial.status, activeStep: state.tutorial.activeStep, - tutorial: state.tutorial.tutorial, + tutorial: state.tutorial.tutorials[0], isLoading: state.tutorial.progress, message: state.message }); diff --git a/src/components/Tutorial/TutorialHome.js b/src/components/Tutorial/TutorialHome.js index a6ffa1a..ff6bccd 100644 --- a/src/components/Tutorial/TutorialHome.js +++ b/src/components/Tutorial/TutorialHome.js @@ -1,14 +1,13 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; +import { getTutorials, resetTutorial } from '../../actions/tutorialActions'; +import { clearMessages } from '../../actions/messageActions'; import clsx from 'clsx'; import Breadcrumbs from '../Breadcrumbs'; -import tutorials from '../../data/tutorials'; -// import tutorials from '../../data/tutorials.json'; - import { Link } from 'react-router-dom'; import { fade } from '@material-ui/core/styles/colorManipulator'; @@ -16,6 +15,7 @@ import { withStyles } from '@material-ui/core/styles'; import Grid from '@material-ui/core/Grid'; import Paper from '@material-ui/core/Paper'; import Typography from '@material-ui/core/Typography'; +import LinearProgress from '@material-ui/core/LinearProgress'; import { faCheck, faTimes } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; @@ -52,14 +52,33 @@ const styles = (theme) => ({ class TutorialHome extends Component { + componentDidMount() { + this.props.getTutorials(); + } + + componentDidUpdate(props, state) { + if(this.props.message.id === 'GET_TUTORIALS_FAIL'){ + alert(this.props.message.msg); + this.props.clearMessages(); + } + } + + componentWillUnmount() { + this.props.resetTutorial(); + if(this.props.message.msg){ + this.props.clearMessages(); + } + } + render() { return ( + this.props.isLoading ? :

Tutorial-Übersicht

- {tutorials.map((tutorial, i) => { + {this.props.tutorials.map((tutorial, i) => { var status = this.props.status.filter(status => status.id === tutorial.id)[0]; var tasks = status.tasks; var error = status.tasks.filter(task => task.type === 'error').length > 0; @@ -101,13 +120,22 @@ class TutorialHome extends Component { } TutorialHome.propTypes = { + getTutorials: PropTypes.func.isRequired, + resetTutorial: PropTypes.func.isRequired, + clearMessages: PropTypes.func.isRequired, status: PropTypes.array.isRequired, change: PropTypes.number.isRequired, + tutorials: PropTypes.array.isRequired, + isLoading: PropTypes.bool.isRequired, + message: PropTypes.object.isRequired }; const mapStateToProps = state => ({ change: state.tutorial.change, - status: state.tutorial.status + status: state.tutorial.status, + tutorials: state.tutorial.tutorials, + isLoading: state.tutorial.progress, + message: state.message }); -export default connect(mapStateToProps, null)(withStyles(styles, { withTheme: true })(TutorialHome)); +export default connect(mapStateToProps, { getTutorials, resetTutorial, clearMessages })(withStyles(styles, { withTheme: true })(TutorialHome)); diff --git a/src/reducers/tutorialReducer.js b/src/reducers/tutorialReducer.js index 23398cd..eb7350e 100644 --- a/src/reducers/tutorialReducer.js +++ b/src/reducers/tutorialReducer.js @@ -1,4 +1,4 @@ -import { TUTORIAL_PROGRESS, GET_TUTORIAL, TUTORIAL_SUCCESS, TUTORIAL_ERROR, TUTORIAL_CHANGE, TUTORIAL_XML, TUTORIAL_ID, TUTORIAL_STEP } from '../actions/types'; +import { TUTORIAL_PROGRESS, GET_TUTORIAL, GET_TUTORIALS, TUTORIAL_SUCCESS, TUTORIAL_ERROR, TUTORIAL_CHANGE, TUTORIAL_XML, TUTORIAL_ID, TUTORIAL_STEP } from '../actions/types'; import tutorials from '../data/tutorials'; @@ -40,11 +40,10 @@ const initialStatus = () => { const initialState = { status: initialStatus(), - // currentId: null, currentIndex: null, activeStep: 0, change: 0, - tutorial: {}, + tutorials: [], progress: false }; @@ -55,11 +54,16 @@ export default function (state = initialState, action) { ...state, progress: !state.progress } + case GET_TUTORIALS: + return { + ...state, + tutorials: action.payload + }; case GET_TUTORIAL: return { ...state, - tutorial: action.payload - }; + tutorials: [action.payload] + } case TUTORIAL_SUCCESS: case TUTORIAL_ERROR: case TUTORIAL_XML: @@ -77,7 +81,6 @@ export default function (state = initialState, action) { case TUTORIAL_ID: return { ...state, - // currentId: action.payload, currentIndex: tutorials.findIndex(tutorial => tutorial.id === action.payload) } case TUTORIAL_STEP: