Home Reference Source

src/components/courses/Course.js

import React, { Component } from "react";
import {
    Button,
    Grid,
    Icon,
    Tooltip,
    LinearProgress
} from "@material-ui/core";
/**
 * React component for navigating the course lessons and displaying lesson name and description 
 */
class Lesson extends Component {
    constructor(props) {
        super(props);
        this.state = {
            currentProgress: 0
        };
    }
    /**
     * Load next lesson. Give a warning if there's any changes in the editor
     */
    nextLesson = () => {
        const currentIndex = this.props.courses.currentIndex;
        const lessons = this.props.course.lessons;
        if(this.hasEditorChanged() && !window.confirm("Are you sure you want to continue?\nYou will lose any unsaved work!")){
            return;
        }
        this.props.courseActions.nextLesson(currentIndex, lessons[currentIndex + 1]);
        this.setState({currentProgress: (((this.props.courses.currentIndex + 1) / (lessons.length - 1)) * 100)});
    }
    /**
     * Load previous lesson. Give a warning if there's any changes in the editor
     */
    lastLesson = () => {
        const currentIndex = this.props.courses.currentIndex;
        const lessons = this.props.course.lessons;
        if(this.hasEditorChanged() && !window.confirm("Are you sure you want to continue?\nYou will lose any unsaved work!")){
            return;
        }
        this.props.courseActions.previousLesson(currentIndex, lessons[currentIndex - 1]);
        this.setState({currentProgress: (((this.props.courses.currentIndex - 1) / (lessons.length - 1))*100)});
    }
    /**
     * Returns wheter the text in the editor match with the savedText
     * @returns {boolean} true if savedText is different from text in editor, false otherwise.
     */
    hasEditorChanged = () => {
        let text;
        try {
            let editor = window.ace.edit("ace-editor");
            text = editor.getSession().getValue();
        } catch (err) {
            console.error(err);
        }
        if (this.props.savedText === text) {
            return false;
        }
        return true;
    }
    /**
     * @returns DOM Elements of button that go to previous or 
     */
    renderBtns = () => {
        const { course, courses } = this.props;
        let nextValid = courses && courses.currentIndex !== null && course && course.lessons;
        let prevValid = courses && courses.currentIndex !== null;
        return (
            <Grid container spacing={48} id="lesson-btns">
                <Grid item xs={2}>
                    <Tooltip title="Previous Lesson" placement="top-start">
                        <Button
                            onClick={() => {
                                this.lastLesson();
                            }}
                            color="primary"
                            disabled={prevValid ? courses.currentIndex <= 0 : true}
                            variant="text"
                            fullWidth={true}
                            className="">
                            <Icon className="material-icons">chevron_left</Icon>
                        </Button>
                    </Tooltip>
                </Grid>
                <Grid item xs={8}></Grid>
                <Grid item xs={2}>
                    <Tooltip title="Next Lesson" placement="top-start">
                        <Button
                            onClick={() => {
                                this.nextLesson();
                            }}
                            color="primary"
                            disabled={nextValid ? courses.currentIndex >= course.lessons.length - 1 : true}
                            variant="text"
                            fullWidth={true}
                            className="">
                            <Icon className="material-icons">chevron_right</Icon>
                        </Button>
                    </Tooltip>
                </Grid>
            </Grid>
        );
    }
    /**
     * @returns Render DOM elements of course lessons 
     */
    render() {
        return (
            <div id="lesson">
                <h3>{(this.props.lesson && this.props.lesson.name) ? this.props.lesson.name : "Loading..."}</h3>
                <p>{(this.props.lesson && this.props.lesson.prompt) ? this.props.lesson.prompt : "Loading..."} </p>
                <this.renderBtns />
                <div>
                    <LinearProgress variant="determinate" value={this.state.currentProgress} />
                </div>
            </div>
        );
    }
}
export default Lesson;