error page requesting a tutorial that does not (longer) exist
This commit is contained in:
		
							parent
							
								
									bcc4c35c9e
								
							
						
					
					
						commit
						ccf901d20b
					
				| @ -1,5 +1,5 @@ | ||||
| .wrapper { | ||||
|   min-height: 100vh; /* will cover the 100% of viewport */ | ||||
|   min-height: calc(100vh - 60px); /* will cover the 100% of viewport - height of footer (padding-bottom) */ | ||||
|   overflow: hidden; | ||||
|   display: block; | ||||
|   position: relative; | ||||
|  | ||||
| @ -58,10 +58,10 @@ export const onChangeWorkspace = (event) => (dispatch, getState) => { | ||||
| 
 | ||||
| export const clearStats = () => (dispatch) => { | ||||
|   var stats = { | ||||
|     create: 0, | ||||
|     create: -1, // initialXML is created automatically, Block is not part of the statistics
 | ||||
|     change: 0, | ||||
|     delete: 0, | ||||
|     move: 0 | ||||
|     move: -1 // initialXML is moved automatically, Block is not part of the statistics
 | ||||
|   }; | ||||
|   dispatch({ | ||||
|     type: CLEAR_STATS, | ||||
|  | ||||
| @ -9,7 +9,7 @@ class MyBreadcrumbs extends Component { | ||||
|   render() { | ||||
|     return ( | ||||
|       this.props.content && this.props.content.length > 1 ? | ||||
|         <Breadcrumbs separator="›"> | ||||
|         <Breadcrumbs separator="›" style={{marginBottom: '20px'}}> | ||||
|           {this.props.content.splice(0, this.props.content.length-1).map((content, i) => ( | ||||
|             <Link to={content.link} style={{textDecoration: 'none'}} key={i}> | ||||
|               <Typography color="secondary">{content.title}</Typography> | ||||
|  | ||||
| @ -1,4 +1,7 @@ | ||||
| import React, { Component } from 'react'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import { connect } from 'react-redux'; | ||||
| import { clearStats } from '../actions/workspaceActions'; | ||||
| 
 | ||||
| import * as Blockly from 'blockly/core'; | ||||
| 
 | ||||
| @ -53,6 +56,10 @@ class Home extends Component { | ||||
|     Blockly.svgResize(workspace); | ||||
|   } | ||||
| 
 | ||||
|   componentWillUnmount(){ | ||||
|     this.props.clearStats(); | ||||
|   } | ||||
| 
 | ||||
|   onChange = () => { | ||||
|     this.setState({ codeOn: !this.state.codeOn }); | ||||
|     const workspace = Blockly.getMainWorkspace(); | ||||
| @ -92,4 +99,9 @@ class Home extends Component { | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| export default withStyles(styles, { withTheme: true })(Home); | ||||
| Home.propTypes = { | ||||
|   clearStats: PropTypes.func.isRequired | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| export default connect(null, { clearStats })(withStyles(styles, { withTheme: true })(Home)); | ||||
|  | ||||
| @ -1,11 +1,41 @@ | ||||
| import React, { Component } from 'react'; | ||||
| 
 | ||||
| import Breadcrumbs from './Breadcrumbs'; | ||||
| 
 | ||||
| import { withRouter } from 'react-router-dom'; | ||||
| 
 | ||||
| import Button from '@material-ui/core/Button'; | ||||
| import Typography from '@material-ui/core/Typography'; | ||||
| 
 | ||||
| class NotFound extends Component { | ||||
|   render() { | ||||
|     return ( | ||||
|       <h1>404 Not Found</h1> | ||||
|       <div> | ||||
|         <Breadcrumbs content={[{link: '/', title: 'Home'}, {link: this.props.location.pathname, title: 'Error'}]}/> | ||||
|         <Typography variant='h4' style={{marginBottom: '5px'}}>Die von Ihnen angeforderte Seite kann nicht gefunden werden.</Typography> | ||||
|         <Typography variant='body1'>Die gesuchte Seite wurde möglicherweise entfernt, ihr Name wurde geändert oder sie ist vorübergehend nicht verfügbar.</Typography> | ||||
|         {this.props.button ? | ||||
|           <Button | ||||
|             style={{marginTop: '20px'}} | ||||
|             variant="contained" | ||||
|             color="primary" | ||||
|             onClick={() => {this.props.history.push(this.props.button.link)}} | ||||
|           > | ||||
|             {this.props.button.title} | ||||
|           </Button> | ||||
|         : | ||||
|           <Button | ||||
|             style={{marginTop: '20px'}} | ||||
|             variant="contained" | ||||
|             color="primary" | ||||
|             onClick={() => {this.props.history.push('/')}} | ||||
|           > | ||||
|             Zurück zur Startseite | ||||
|           </Button> | ||||
|         } | ||||
|       </div> | ||||
|     ); | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| export default NotFound; | ||||
| export default withRouter(NotFound); | ||||
|  | ||||
| @ -1,10 +1,11 @@ | ||||
| import React, { Component } from 'react'; | ||||
| 
 | ||||
| import { withRouter, Link } from 'react-router-dom'; | ||||
| import { withRouter } from 'react-router-dom'; | ||||
| 
 | ||||
| import Breadcrumbs from '../Breadcrumbs'; | ||||
| import BlocklyWindow from '../Blockly/BlocklyWindow'; | ||||
| import CodeViewer from '../CodeViewer'; | ||||
| import NotFound from '../NotFound'; | ||||
| 
 | ||||
| import tutorials from './tutorials.json'; | ||||
| 
 | ||||
| @ -47,29 +48,33 @@ class Tutorial extends Component { | ||||
|   } | ||||
| 
 | ||||
|   render() { | ||||
|     var tutorialId = Number(this.props.match.params.tutorialId); | ||||
|     return ( | ||||
|       !Number.isInteger(tutorialId) || tutorialId < 1 || tutorialId > tutorials.length ? | ||||
|       <NotFound button={{title: 'Zurück zur Tutorials-Übersicht', link: '/tutorial'}}/> | ||||
|         : | ||||
|       <div> | ||||
|         <Breadcrumbs content={[{link: '/', title: 'Home'},{link: '/tutorial', title: 'Tutorial'}, {link: `/tutorial/${this.props.match.params.tutorialId}`, title: this.props.match.params.tutorialId}]}/> | ||||
|         <Breadcrumbs content={[{link: '/', title: 'Home'},{link: '/tutorial', title: 'Tutorial'}, {link: `/tutorial/${tutorialId}`, title: tutorials[tutorialId-1].title}]}/> | ||||
| 
 | ||||
|         {/* Stepper */} | ||||
|         <div className={this.props.classes.stepper}> | ||||
|           <Button | ||||
|             disabled={parseInt(this.props.match.params.tutorialId)-1 === 0} | ||||
|             onClick={() => {this.props.history.push(`/tutorial/${parseInt(this.props.match.params.tutorialId)-1}`)}} | ||||
|             disabled={tutorialId-1 === 0} | ||||
|             onClick={() => {this.props.history.push(`/tutorial/${tutorialId-1}`)}} | ||||
|           > | ||||
|             {'<'} | ||||
|           </Button> | ||||
|           <Stepper activeStep={this.props.match.params.tutorialId} orientation="horizontal" | ||||
|           <Stepper activeStep={tutorialId} orientation="horizontal" | ||||
|                    style={{padding: 0}} classes={{root: this.props.classes.color}}> | ||||
|             <Step expanded completed={false}> | ||||
|               <StepLabel icon={``}> | ||||
|                 <h1 style={{margin: 0}}>Tutorial {this.props.match.params.tutorialId}</h1> | ||||
|                 <h1 style={{margin: 0}}>{tutorials[tutorialId-1].title}</h1> | ||||
|               </StepLabel> | ||||
|             </Step> | ||||
|           </Stepper> | ||||
|           <Button | ||||
|             disabled={parseInt(this.props.match.params.tutorialId)+1 > tutorials.length} | ||||
|             onClick={() => {this.props.history.push(`/tutorial/${parseInt(this.props.match.params.tutorialId)+1}`)}} | ||||
|             disabled={tutorialId+1 > tutorials.length} | ||||
|             onClick={() => {this.props.history.push(`/tutorial/${tutorialId+1}`)}} | ||||
|           > | ||||
|             {'>'} | ||||
|           </Button> | ||||
|  | ||||
| @ -20,7 +20,7 @@ class TutorialHome extends Component { | ||||
|           {tutorials.map((tutorial, i) => ( | ||||
|             <Grid item xs={12} sm={6} md={4} xl={3} key={i}> | ||||
|               <Link to={`/tutorial/${i+1}`} style={{textDecoration: 'none', color: 'inherit'}}> | ||||
|                 <Paper style={{height: '150px', padding: '10px'}}>Tutorial {i+1}</Paper> | ||||
|                 <Paper style={{height: '150px', padding: '10px'}}>{tutorials[i].title}</Paper> | ||||
|               </Link> | ||||
|             </Grid> | ||||
|           ))} | ||||
|  | ||||
| @ -1 +1,11 @@ | ||||
| [{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}] | ||||
| [ | ||||
|   { | ||||
|     "title": "erste Schritte" | ||||
|   }, | ||||
|   { | ||||
|     "title": "if-Bedingung" | ||||
|   }, | ||||
|   { | ||||
|     "title": "for-Schleife" | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -42,7 +42,7 @@ class WorkspaceStats extends Component { | ||||
|             style={{ marginRight: '1rem' }} | ||||
|             color="primary" | ||||
|             avatar={<Avatar><FontAwesomeIcon icon={faPlus} /></Avatar>} | ||||
|             label={this.props.create}> | ||||
|             label={this.props.create > 0 ? this.props.create : 0}> // initialXML is created automatically, Block is not part of the statistics
 | ||||
|           </Chip> | ||||
|         </Tooltip> | ||||
|         <Tooltip title="Anzahl veränderter Blöcke" > | ||||
| @ -58,7 +58,7 @@ class WorkspaceStats extends Component { | ||||
|             style={{ marginRight: '1rem' }} | ||||
|             color="primary" | ||||
|             avatar={<Avatar><FontAwesomeIcon icon={faArrowsAlt} /></Avatar>} | ||||
|             label={this.props.move}> | ||||
|             label={this.props.move > 0 ? this.props.move : 0}> // initialXML is moved automatically, Block is not part of the statistics
 | ||||
|           </Chip> | ||||
|         </Tooltip> | ||||
|         <Tooltip title="Anzahl gelöschter Blöcke" > | ||||
|  | ||||
| @ -7,10 +7,10 @@ const initialState = { | ||||
|     xml: '' | ||||
|   }, | ||||
|   stats: { | ||||
|     create: 0, | ||||
|     create: -1, // initialXML is created automatically, Block is not part of the statistics
 | ||||
|     change: 0, | ||||
|     delete: 0, | ||||
|     move: 0 | ||||
|     move: -1 // initialXML is moved automatically, Block is not part of the statistics
 | ||||
|   }, | ||||
|   change: 0 | ||||
| }; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user