added Tutorial Builder FinalPage

This commit is contained in:
fab-scm 2022-11-24 11:45:58 +01:00
parent 77b338ffb6
commit 912440f64c
5 changed files with 225 additions and 58 deletions

View File

@ -301,12 +301,20 @@ export const resetTutorial = () => (dispatch, getState) => {
hardware: [],
requirements: [],
},
{
id: 2,
type: "instruction",
headline: "",
text: "",
finalpage: true,
solutions: [],
},
];
dispatch(tutorialSteps(steps));
dispatch({
type: BUILDER_ERROR,
payload: {
steps: [{}],
steps: [{}, {}],
},
});
};

View File

@ -273,6 +273,7 @@ class Builder extends Component {
} else {
// export steps without attribute 'url'
var steps = this.props.steps;
var length = steps.length;
var newTutorial = new FormData();
newTutorial.append("title", this.props.title);
newTutorial.append("difficulty", this.props.difficulty);
@ -299,11 +300,28 @@ class Builder extends Component {
newTutorial.append(`steps[${i}][hardware][${j}]`, hardware);
});
}
if (i === length-1 && step.finalpage) {
newTutorial.append(`steps[${i}][finalpage]`, step.finalpage);
newTutorial.append(`steps[${i}][samplesolutions]`, step.samplesolutions);
newTutorial.append(`steps[${i}][furthertutorials]`, step.furthertutorials);
}
// 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);
}
});
for (const pair of newTutorial.entries()) {
console.log(`${pair[0]}, ${pair[1]}`);
}
return newTutorial;
}
};

View File

@ -0,0 +1,107 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { changeContent } from "../../../actions/tutorialBuilderActions";
import { withStyles } from "@material-ui/core/styles";
import Switch from "@material-ui/core/Switch";
import FormGroup from '@material-ui/core/FormGroup';
import FormControlLabel from "@material-ui/core/FormControlLabel";
const styles = (theme) => ({
errorColor: {
color: theme.palette.error.dark,
},
errorBorder: {
border: `1px solid ${theme.palette.error.dark}`,
},
errorButton: {
marginTop: "5px",
height: "40px",
backgroundColor: theme.palette.error.dark,
"&:hover": {
backgroundColor: theme.palette.error.dark,
},
},
});
class FinalPageOptions extends Component {
constructor(props) {
super(props);
this.state = {
checkedSampleSolutions: props.checkedSampleSolutions,
checkedFurtherTutorials: props.checkedFurtherTutorials,
};
}
onChangeSampleSolutions = (value) => {
var oldValue = this.state.checked;
this.setState({ checked: value });
if (oldValue !== value) {
this.props.changeContent(value, this.props.index, "samplesolutions");
}
};
onChangeFurtherTutorials = (value) => {
var oldValue = this.state.checked;
this.setState({ checked: value });
if (oldValue !== value) {
this.props.changeContent(value, this.props.index, "furthertutorials");
}
}
render() {
var steps = this.props.steps;
return (
<div
style={{
marginBottom: "10px",
padding: "18.5px 14px",
borderRadius: "25px",
border: "1px solid lightgrey",
width: "calc(100% - 28px)",
}}
>
<FormGroup>
<FormControlLabel
labelPlacement="end"
label={
"Musterlösung(en) der Aufgabe(n) auf der Abschlussseite anzeigen"
}
control={
<Switch
checked={this.state.checked}
onChange={(e) => this.onChangeSampleSolutions(e.target.checked)}
color="primary"
/>
}
/>
<FormControlLabel
labelPlacement="end"
label={
"Vorschläge für weitere Tutorials auf der Abschlussseite anzeigen"
}
control={
<Switch
checked={this.state.checked}
onChange={(e) => this.onChangeFurtherTutorials(e.target.checked)}
color="primary"
/>
}
/>
</FormGroup>
</div>
);
}
}
FinalPageOptions.propTypes = {
changeContent: PropTypes.func.isRequired,
};
const mapStateToProps = (state) => ({
});
export default connect(mapStateToProps, {
changeContent,
})(withStyles(styles, { withTheme: true })(FinalPageOptions));

View File

@ -29,6 +29,7 @@ import {
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import MarkdownEditor from "./MarkdownEditor";
import FinalPageOptions from "./FinalPageOptions";
const styles = (theme) => ({
button: {
@ -64,12 +65,21 @@ class Step extends Component {
marginBottom: "20px",
}}
>
<Typography
variant="h6"
style={{ marginBottom: "10px", marginLeft: "4px" }}
>
Schritt {index + 1}
</Typography>
{ !this.props.step.finalpage ? (
<Typography
variant="h6"
style={{ marginBottom: "10px", marginLeft: "4px" }}
>
Schritt {index + 1}
</Typography>
) : (
<Typography
variant="h6"
style={{ marginBottom: "10px", marginLeft: "4px" }}
>
Abschlussseite
</Typography>
)}
<div style={{ display: "flex", position: "relative" }}>
<div
style={{
@ -80,60 +90,66 @@ class Step extends Component {
bottom: "10px",
}}
>
<Tooltip title="Schritt hinzufügen" arrow>
<IconButton
className={this.props.classes.button}
style={index === 0 ? {} : { marginBottom: "5px" }}
onClick={() => this.props.addStep(index + 1)}
>
<FontAwesomeIcon icon={faPlus} size="xs" />
</IconButton>
</Tooltip>
{index !== 0 ? (
{!this.props.step.finalpage ? (
<div>
<Tooltip
title={`Schritt ${index + 1} nach oben schieben`}
arrow
>
<Tooltip title="Schritt hinzufügen" arrow>
<IconButton
disabled={index < 2}
className={this.props.classes.button}
style={{ marginBottom: "5px" }}
onClick={() => this.props.changeStepIndex(index, index - 1)}
style={index === 0 ? {} : { marginBottom: "5px" }}
onClick={() => this.props.addStep(index + 1)}
>
<FontAwesomeIcon icon={faAngleDoubleUp} size="xs" />
</IconButton>
</Tooltip>
<Tooltip
title={`Schritt ${index + 1} nach unten schieben`}
arrow
>
<IconButton
disabled={index === steps.length - 1}
className={this.props.classes.button}
style={{ marginBottom: "5px" }}
onClick={() => this.props.changeStepIndex(index, index + 1)}
>
<FontAwesomeIcon icon={faAngleDoubleDown} size="xs" />
</IconButton>
</Tooltip>
<Tooltip title={`Schritt ${index + 1} löschen`} arrow>
<IconButton
disabled={index === 0}
className={clsx(
this.props.classes.button,
this.props.classes.delete
)}
onClick={() => this.props.removeStep(index)}
>
<FontAwesomeIcon icon={faTrash} size="xs" />
<FontAwesomeIcon icon={faPlus} size="xs" />
</IconButton>
</Tooltip>
{index !== 0 ? (
<div>
<Tooltip
title={`Schritt ${index + 1} nach oben schieben`}
arrow
>
<IconButton
disabled={index < 2}
className={this.props.classes.button}
style={{ marginBottom: "5px" }}
onClick={() => this.props.changeStepIndex(index, index - 1)}
>
<FontAwesomeIcon icon={faAngleDoubleUp} size="xs" />
</IconButton>
</Tooltip>
<Tooltip
title={`Schritt ${index + 1} nach unten schieben`}
arrow
>
<IconButton
disabled={index >= this.props.steps.length - 2}
className={this.props.classes.button}
style={{ marginBottom: "5px" }}
onClick={() => this.props.changeStepIndex(index, index + 1)}
>
<FontAwesomeIcon icon={faAngleDoubleDown} size="xs" />
</IconButton>
</Tooltip>
<Tooltip title={`Schritt ${index + 1} löschen`} arrow>
<IconButton
disabled={index === 0 && index === steps.length - 1}
className={clsx(
this.props.classes.button,
this.props.classes.delete
)}
onClick={() => this.props.removeStep(index)}
>
<FontAwesomeIcon icon={faTrash} size="xs" />
</IconButton>
</Tooltip>
</div>
) : null}
</div>
) : null}
</div>
<div style={{ width: "100%", marginLeft: "54px" }}>
<StepType value={this.props.step.type} index={index} />
{!this.props.step.finalpage ? (
<StepType value={this.props.step.type} index={index} />
) : null}
<Textfield
value={this.props.step.headline}
property={"headline"}
@ -178,12 +194,21 @@ class Step extends Component {
/>
</div>
) : null}
<BlocklyExample
value={this.props.step.xml}
index={index}
task={this.props.step.type === "task"}
error={this.props.error.steps[index].xml ? true : false}
/>
{ !this.props.step.finalpage ? (
<BlocklyExample
value={this.props.step.xml}
index={index}
task={this.props.step.type === "task"}
error={this.props.error.steps[index].xml ? true : false}
/>
) : (
<FinalPageOptions
steps={steps}
checkedSampleSolutions={this.props.step.samplesolutions}
checkedFurtherTutorials={this.props.step.furtherTutorials}
index={index}
/>
)}
</div>
</div>
</div>

View File

@ -33,9 +33,18 @@ const initialState = {
hardware: [],
requirements: [],
},
{
id: 2,
type: "instruction",
headline: "",
text: "",
finalpage: true,
samplesolutions: false,
furtherTutorials: false,
},
],
error: {
steps: [{}],
steps: [{},{}],
},
};