diff --git a/src/actions/tutorialBuilderActions.js b/src/actions/tutorialBuilderActions.js
index 5fe4493..3ed8289 100644
--- a/src/actions/tutorialBuilderActions.js
+++ b/src/actions/tutorialBuilderActions.js
@@ -303,11 +303,12 @@ export const resetTutorial = () => (dispatch, getState) => {
},
{
id: 2,
- type: "instruction",
+ type: "finalpage",
headline: "",
text: "",
- finalpage: true,
+ samplesolutions: false,
solutions: [],
+ furthertutorials: false,
},
];
dispatch(tutorialSteps(steps));
diff --git a/src/components/Tutorial/Builder/Builder.js b/src/components/Tutorial/Builder/Builder.js
index bff8019..5dfa661 100644
--- a/src/components/Tutorial/Builder/Builder.js
+++ b/src/components/Tutorial/Builder/Builder.js
@@ -259,7 +259,7 @@ class Builder extends Component {
window.scrollTo(0, 0);
};
- submit = () => {
+ submit = () => {;
var isError = this.props.checkError();
if (isError) {
this.setState({
@@ -273,6 +273,7 @@ class Builder extends Component {
} else {
// export steps without attribute 'url'
var steps = this.props.steps;
+ // console.log(steps);
var length = steps.length;
var newTutorial = new FormData();
newTutorial.append("title", this.props.title);
@@ -300,20 +301,22 @@ class Builder extends Component {
newTutorial.append(`steps[${i}][hardware][${j}]`, hardware);
});
}
- if (i === length-1 && step.finalpage) {
- newTutorial.append(`steps[${i}][finalpage]`, step.finalpage);
+ if (i === length-1 && step.type === "finalpage") {
newTutorial.append(`steps[${i}][samplesolutions]`, step.samplesolutions);
newTutorial.append(`steps[${i}][furthertutorials]`, step.furthertutorials);
+
+ if (step.samplesolutions === true) {
+ var solutionindex = 0;
+ steps.forEach((solutionstep) => {
+ if (solutionstep.type === "task"&& solutionstep.xml) {
+ newTutorial.append(`steps[${i}][solutions][${solutionindex}][type]`, solutionstep.type);
+ newTutorial.append(`steps[${i}][solutions][${solutionindex}][headline]`, solutionstep.headline);
+ newTutorial.append(`steps[${i}][solutions][${solutionindex}][xml]`, solutionstep.xml);
+ solutionindex++;
+ }
+ });
+ }
}
- // if (i === length-1 && step.type === "instruction" && step.samplesolutions === true) {
- // var solutions = [];
- // steps.forEach((step) => {
- // if (step.type === "task") {
- // solutions.push(step)
- // }
- // });
- // newTutorial.append(`steps[${i}][samplesolutions]`, solutions);
- // }
if (step.xml) {
// optional
newTutorial.append(`steps[${i}][xml]`, step.xml);
diff --git a/src/components/Tutorial/Builder/Step.js b/src/components/Tutorial/Builder/Step.js
index 4a23093..2b21e43 100644
--- a/src/components/Tutorial/Builder/Step.js
+++ b/src/components/Tutorial/Builder/Step.js
@@ -56,6 +56,8 @@ class Step extends Component {
render() {
var index = this.props.index;
var steps = this.props.steps;
+ // console.log(this.props.steps);
+ // console.log(this.props.step);
return (
- { !this.props.step.finalpage ? (
+ {this.props.step.type !== "finalpage" ? (
- {!this.props.step.finalpage ? (
+ {this.props.step.type !== "finalpage" ? (
- {!this.props.step.finalpage ? (
+ {this.props.step.type !== "finalpage" ? (
) : null}
) : null}
- { !this.props.step.finalpage ? (
+ {this.props.step.type !== "finalpage" ? (
)}
diff --git a/src/components/Tutorial/FinalPage.js b/src/components/Tutorial/FinalPage.js
new file mode 100644
index 0000000..05b021a
--- /dev/null
+++ b/src/components/Tutorial/FinalPage.js
@@ -0,0 +1,430 @@
+import React, { Component } from "react";
+import { connect } from "react-redux";
+import axios from "axios";
+
+import BlocklyWindow from "../Blockly/BlocklyWindow";
+
+import clsx from "clsx";
+import { alpha } from "@material-ui/core/styles";
+import { withStyles } from "@material-ui/core/styles";
+
+import {
+ faCheck,
+ faTimes,
+} from "@fortawesome/free-solid-svg-icons";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { Link } from "react-router-dom";
+import ReactStars from "react-rating-stars-component";
+import Grid from "@material-ui/core/Grid";
+import Typography from "@material-ui/core/Typography";
+import Paper from "@material-ui/core/Paper";
+import ReactMarkdown from "react-markdown";
+import remarkGfm from "remark-gfm";
+import remarkGemoji from "remark-gemoji";
+import Dialog from "../Dialog";
+import { IconButton } from "@material-ui/core";
+import { clearMessages } from "../../actions/messageActions";
+
+import * as Blockly from "blockly/core";
+
+// import { getTutorials,
+// tutorialProgress,
+// resetTutorial
+// } from "../../actions/tutorialActions";
+
+
+
+const styles = (theme) => ({
+ outerDiv: {
+ position: "absolute",
+ right: "-30px",
+ bottom: "-30px",
+ width: "160px",
+ height: "160px",
+ color: alpha(theme.palette.secondary.main, 0.6),
+ },
+ outerDivError: {
+ stroke: alpha(theme.palette.error.dark, 0.6),
+ color: alpha(theme.palette.error.dark, 0.6),
+ },
+ outerDivSuccess: {
+ stroke: alpha(theme.palette.primary.main, 0.6),
+ color: alpha(theme.palette.primary.main, 0.6),
+ },
+ outerDivOther: {
+ stroke: alpha(theme.palette.secondary.main, 0.6),
+ },
+ innerDiv: {
+ width: "inherit",
+ height: "inherit",
+ display: "table-cell",
+ verticalAlign: "middle",
+ textAlign: "center",
+ },
+ // button: {
+ // backgroundColor: theme.palette.primary.main,
+ // color: theme.palette.primary.contrastText,
+ // width: "40px",
+ // height: "40px",
+ // "&:hover": {
+ // backgroundColor: theme.palette.primary.main,
+ // color: theme.palette.primary.contrastText,
+ // },
+ // },
+ // link: {
+ // color: theme.palette.primary.main,
+ // textDecoration: "none",
+ // "&:hover": {
+ // color: theme.palette.primary.main,
+ // textDecoration: "underline",
+ // },
+ // },
+});
+
+class FinalPage extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ open: false,
+ title: "",
+ content: "",
+ tutorials: [],
+ randomtutorials: [],
+ activeXML: "",
+ };
+ }
+
+ componentWillMount() {
+ if (this.props.step.furthertutorials === true) {
+ axios
+ .get(`${process.env.REACT_APP_BLOCKLY_API}/tutorial`)
+ .then((res) => {
+ this.setState({ tutorials: res.data.tutorials });
+ this.setState({ randomtutorials: this.getRandomTutorials(this.state.tutorials, 3) });
+ })
+ }
+ }
+
+ toggleDialog = (solution) => {
+ console.log(solution)
+ if (this.state.open === true) {
+ this.setState({ open: !this.state.open, title: "", activeXML: "" });
+ } else if (this.state.open === false) {
+ this.setState({ open: !this.state.open, title: "Task - " + solution.headline, activeXML: solution.xml });
+ }
+
+ };
+
+
+ getRandomTutorials = (tutorials, n) => {
+ var length = tutorials.length;
+ var taken = new Array(length);
+ var result = new Array(n);
+ if (n > length)
+ throw new RangeError("getRandom: more elements taken than available");
+ while (n--) {
+ var x = Math.floor(Math.random() * length);
+ result[n] = tutorials[x in taken ? taken[x] : x];
+ taken[x] = --length in taken ? taken[length] : length;
+ }
+ return result;
+ }
+
+ // toggleDialog = (solution) => {
+ // this.setState({ open: !this.state.open });
+ // // if (solution) {
+ // // this.setState({ open: !this.state.open, activeSolution: solution });
+ // // } else {
+ // // this.setState({ open: !this.state.open, activeSolution: null });
+ // // }
+ // };
+
+ render() {
+ var step = this.props.step;
+ var tutorials = this.state.tutorials;
+ var randomtutorials = this.state.randomtutorials;
+ // var randomtutorials = this.getRandomTutorials(tutorials, 3);
+ // console.log(randomtutorials)
+ return (
+
+
+
+ {step.text}
+
+
+ {step.media ? (
+ step.media.picture ? (
+
+

+
+ ) : step.media.youtube ? (
+ /*16:9; width: 800px; height: width/16*9=450px*/
+
+ ) : null
+ ) : null}
+ {step.samplesolutions === true ? (
+
+
Musterlösungen
+
+ {step.solutions.map((solution) => {
+ return (
+
+ this.toggleDialog(solution)}
+ >
+
+ {"Task - " + solution.headline}
+
+
+
+
+ );
+ })}
+
+
+
+
+
+ ) : null}
+
+
+
+ {step.furthertutorials === true ? (
+
+
Weitere Tutorials
+
+ {randomtutorials.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;
+ var success =
+ status.tasks.filter((task) => task.type === "success").length /
+ tasks.length;
+ var tutorialStatus =
+ success === 1 ? "Success" : error ? "Error" : "Other";
+ const firstExample = {
+ size: 30,
+ value: tutorial.difficulty,
+ edit: false,
+ isHalf: true,
+ };
+ return (
+
+
+
+ {tutorial.title}
+
+
+
+
+
+
+ {error || success === 1 ? (
+
+ ) : (
+ 0
+ ? this.props.classes.outerDivSuccess
+ : {}
+ }
+ >
+ {Math.round(success * 100)}%
+
+ )}
+
+
+
+
+
+ );
+ })}
+
+
+ ) : null}
+
+
+ );
+ }
+}
+
+const mapStateToProps = (state) => ({
+ tutorials: state.tutorial.tutorials,
+ status: state.tutorial.status,
+ isLoading: state.tutorial.progress,
+ message: state.message,
+ progress: state.auth.progress,
+ user: state.auth.user,
+ authProgress: state.auth.progress,
+});
+
+export default connect(mapStateToProps, {
+ // getTutorials,
+ // resetTutorial,
+ // tutorialProgress,
+ clearMessages,
+})(withStyles(styles, { withTheme: true })(FinalPage));
diff --git a/src/components/Tutorial/StepperVertical.js b/src/components/Tutorial/StepperVertical.js
index b1fa614..288859d 100644
--- a/src/components/Tutorial/StepperVertical.js
+++ b/src/components/Tutorial/StepperVertical.js
@@ -31,6 +31,9 @@ const styles = (theme) => ({
width: "24px",
height: "24px",
},
+ stepIconSuccess: {
+ borderColor: theme.palette.primary.main,
+ },
stepIconLargeSuccess: {
borderColor: theme.palette.primary.main,
},
@@ -130,12 +133,25 @@ class StepperVertical extends Component {
"stepIconLarge" + taskStatus
]
)
- : i === activeStep
- ? clsx(
- this.props.classes.stepIcon,
- this.props.classes.stepIconActiveOther
- )
- : clsx(this.props.classes.stepIcon),
+ : step.type === "instruction"
+ ? i === activeStep
+ ? clsx(
+ this.props.classes.stepIcon,
+ this.props.classes.stepIconActiveOther
+ )
+ : clsx(this.props.classes.stepIcon)
+ : step.type === "finalpage"
+ ? i === activeStep
+ ? clsx(
+ this.props.classes.stepIcon,
+ this.props.classes.stepIconSuccess,
+ this.props.classes.stepIconActiveSuccess
+ )
+ : clsx(
+ this.props.classes.stepIcon,
+ this.props.classes.stepIconSuccess
+ )
+ : null,
}}
>
diff --git a/src/components/Tutorial/Tutorial.js b/src/components/Tutorial/Tutorial.js
index 1e4d3d8..afd722d 100644
--- a/src/components/Tutorial/Tutorial.js
+++ b/src/components/Tutorial/Tutorial.js
@@ -17,6 +17,7 @@ import StepperHorizontal from "./StepperHorizontal";
import StepperVertical from "./StepperVertical";
import Instruction from "./Instruction";
import Assessment from "./Assessment";
+import FinalPage from "./FinalPage";
import NotFound from "../NotFound";
import * as Blockly from "blockly";
import { detectWhitespacesAndReturnReadableResult } from "../../helpers/whitespace";
@@ -74,7 +75,9 @@ class Tutorial extends Component {
(() => {
var tutorial = this.props.tutorial;
var steps = this.props.tutorial.steps;
+ console.log(steps)
var step = steps[this.props.activeStep];
+ console.log(step)
var name = `${detectWhitespacesAndReturnReadableResult(
tutorial.title
)}_${detectWhitespacesAndReturnReadableResult(step.headline)}`;
@@ -107,8 +110,10 @@ class Tutorial extends Component {
{step ? (
step.type === "instruction" ? (
- ) : (
+ ) : step.type === "task" ? (
+ ) : (
+
) // if step.type === 'assessment'
) : null}
diff --git a/src/reducers/tutorialBuilderReducer.js b/src/reducers/tutorialBuilderReducer.js
index e65c83d..0bba970 100644
--- a/src/reducers/tutorialBuilderReducer.js
+++ b/src/reducers/tutorialBuilderReducer.js
@@ -35,12 +35,12 @@ const initialState = {
},
{
id: 2,
- type: "instruction",
+ type: "finalpage",
headline: "",
text: "",
- finalpage: true,
samplesolutions: false,
- furtherTutorials: false,
+ solutions: [],
+ furthertutorials: false,
},
],
error: {