load pictures from the api server

This commit is contained in:
Delucse 2020-11-30 13:44:05 +01:00
parent a2c571c1e7
commit c8f01f8273
6 changed files with 53 additions and 31 deletions

View File

@ -189,7 +189,7 @@ export const setSubmitError = () => (dispatch, getState) => {
step.id = i + 1;
if (i === 0) {
if (step.requirements && step.requirements.length > 0) {
var requirements = step.requirements.filter(requirement => typeof (requirement) === 'number');
var requirements = step.requirements.filter(requirement => /^[0-9a-fA-F]{24}$/.test(requirement));
if (requirements.length < step.requirements.length) {
dispatch(changeContent(requirements, i, 'requirements'));
}

View File

@ -3,8 +3,9 @@ import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { checkError, readJSON, jsonString, progress, resetTutorial } from '../../../actions/tutorialBuilderActions';
import { saveAs } from 'file-saver';
import axios from 'axios';
import { saveAs } from 'file-saver';
import { detectWhitespacesAndReturnReadableResult } from '../../../helpers/whitespace';
import Breadcrumbs from '../../Breadcrumbs';
@ -51,12 +52,6 @@ class Builder extends Component {
}
submit = () => {
if (this.props.id === null) {
var randomID = Date.now();
} else {
randomID = this.props.id;
}
var isError = this.props.checkError();
if (isError) {
this.setState({ snackbar: true, key: Date.now(), message: `Die Angaben für das Tutorial sind nicht vollständig.`, type: 'error' });
@ -64,19 +59,46 @@ class Builder extends Component {
}
else {
// export steps without attribute 'url'
var steps = this.props.steps.map(step => {
if (step.url) {
delete step.url;
var steps = this.props.steps;
var newTutorial = new FormData();
newTutorial.append('title', this.props.title);
steps.forEach((step, i) => {
newTutorial.append(`steps[${i}][type]`, step.type);
newTutorial.append(`steps[${i}][headline]`, step.headline);
newTutorial.append(`steps[${i}][text]`, step.text);
if(i === 0 && step.type === 'instruction'){
if(step.requirements){ // optional
step.requirements.forEach((requirement, j) => {
newTutorial.append(`steps[${i}][requirements][${j}]`, requirement);
});
}
step.hardware.forEach((hardware, j) => {
newTutorial.append(`steps[${i}][hardware][${j}]`, hardware);
});
}
if(step.xml){ // optional
newTutorial.append(`steps[${i}][xml]`, step.xml);
}
if(step.media){ // optional
if(step.media.youtube){
newTutorial.append(`steps[${i}][media][youtube]`, step.media.youtube);
}
if(step.media.picture){
newTutorial.append(`steps[${i}][media][picture]`, step.media.picture);
}
}
return step;
});
var tutorial = {
id: randomID,
title: this.props.title,
steps: steps
}
var blob = new Blob([JSON.stringify(tutorial)], { type: 'text/json' });
saveAs(blob, `${detectWhitespacesAndReturnReadableResult(tutorial.title)}.json`);
axios.post(`${process.env.REACT_APP_BLOCKLY_API}/tutorial/`, newTutorial)
.then(res => {
var tutorial = res.data.tutorial;
this.props.history.push(`/tutorial/${tutorial._id}`);
})
.catch(err => {
this.setState({ snackbar: true, key: Date.now(), message: `Fehler beim Erstellen des Tutorials. Versuche es noch einmal.`, type: 'error' });
window.scrollTo(0, 0);
});
// var blob = new Blob([JSON.stringify(tutorial)], { type: 'text/json' });
// saveAs(blob, `${detectWhitespacesAndReturnReadableResult(tutorial.title)}.json`);
}
}

View File

@ -84,7 +84,7 @@ class Media extends Component {
this.setState({ error: false });
this.props.changeContent(URL.createObjectURL(pic), this.props.index, 'url');
}
this.props.changeContent(pic.name, this.props.index, 'media', 'picture');
this.props.changeContent(pic, this.props.index, 'media', 'picture');
}
render() {

View File

@ -34,7 +34,7 @@ class Requirements extends Component {
onChange = (e) => {
var requirements = this.props.value;
var value = parseInt(e.target.value)
var value = e.target.value;
if (e.target.checked) {
requirements.push(value);
}
@ -55,8 +55,8 @@ class Requirements extends Component {
key={i}
control={
<Checkbox
value={tutorial.id}
checked={this.props.value.filter(id => id === tutorial.id).length > 0}
value={tutorial._id}
checked={this.props.value.filter(id => id === tutorial._id).length > 0}
onChange={(e) => this.onChange(e)}
name="requirements"
color="primary"

View File

@ -22,11 +22,11 @@ class Instruction extends Component {
{isHardware ?
<Hardware picture={step.hardware} /> : null}
{areRequirements > 0 ?
<Requirement tutorialIds={step.requirements} /> : null}
<Requirement requirements={step.requirements} /> : null}
{step.media ?
step.media.picture ?
<div style={{ display: 'flex', justifyContent: 'center', marginBottom: '5px' }}>
<img src={`/media/tutorial/${step.media.picture}`} alt='' style={{ maxHeight: '40vH', maxWidth: '100%' }} />
<img src={`${process.env.REACT_APP_BLOCKLY_API}/media/${step.media.picture.path}`} alt='' style={{ maxHeight: '40vH', maxWidth: '100%' }} />
</div>
: step.media.youtube ?
/*16:9; width: 800px; height: width/16*9=450px*/

View File

@ -59,14 +59,14 @@ const styles = theme => ({
class Requirement extends Component {
render() {
var tutorialIds = this.props.tutorialIds;
var requirements = this.props.requirements;
var tutorialIds = requirements.map(requirement => requirement._id);
return (
<div style={{ marginTop: '20px', marginBottom: '5px' }}>
<Typography>Bevor du mit diesem Tutorial fortfährst solltest du folgende Tutorials erfolgreich abgeschlossen haben:</Typography>
<List component="div">
{tutorialIds.map((tutorialId, i) => {
// title must be provided together with ids
// var title = tutorials.filter(tutorial => tutorial.id === tutorialId)[0].title;
var title = requirements[i].title
var status = this.props.status.filter(status => status._id === tutorialId)[0];
var tasks = status.tasks;
var error = status.tasks.filter(task => task.type === 'error').length > 0;
@ -98,7 +98,7 @@ class Requirement extends Component {
</div>
</Tooltip>
<div style={{ height: '50px', width: 'calc(100% - 25px)', transform: 'translate(25px)' }} className={this.props.classes.hoverLink}>
<Typography style={{ margin: 0, position: 'absolute', top: '50%', transform: 'translate(45px, -50%)', maxHeight: '50px', overflow: 'hidden', maxWidth: 'calc(100% - 45px)'/*, textOverflow: 'ellipsis', whiteSpace: 'pre-line', overflowWrap: 'anywhere'*/ }}>{/*title*/}Name hinzufügen über Datenbankeintrag</Typography>
<Typography style={{ margin: 0, position: 'absolute', top: '50%', transform: 'translate(45px, -50%)', maxHeight: '50px', overflow: 'hidden', maxWidth: 'calc(100% - 45px)', textOverflow: 'ellipsis', whiteSpace: 'pre-line', overflowWrap: 'anywhere' }}>{title}</Typography>
</div>
</Link>
)
@ -112,12 +112,12 @@ class Requirement extends Component {
Requirement.propTypes = {
status: PropTypes.array.isRequired,
change: PropTypes.number.isRequired,
change: PropTypes.number.isRequired
};
const mapStateToProps = state => ({
change: state.tutorial.change,
status: state.tutorial.status
status: state.tutorial.status,
});
export default connect(mapStateToProps, null)(withStyles(styles, { withTheme: true })(withRouter(Requirement)));