- Read Tutorial
- Watch Guide Video
So, let's go ahead and get started by going into our progressTracker.js and creating a function that's called calculateProgress .bind to this.
progressTracker.js
import React, { Component } from 'react'; class ProgressTracker extends Component { calculateProgress = function() { }.bind(this); render() { return ( <div className="progress-tracker"> <label className="progress-tracker__label">Progress Tracker</label> <div className="progress-tracker__percentage"> {this.calculateProgress()}% </div> </div> ) } } export default ProgressTracker;
Okay, so now what we want to do is replace the 0% with this.calculateProgress and call it like a function.
progressTracker.js
import React, { Component } from 'react'; class ProgressTracker extends Component { calculateProgress = function() { }.bind(this); render() { return ( <div className="progress-tracker"> <label className="progress-tracker__label">Progress Tracker</label> <div className="progress-tracker__percentage"> {this.calculateProgress()}% </div> </div> ) } } export default ProgressTracker;
Now this needs to return a number, we could say 0 or we could calculate it, so lets calculate it. So what we want to do is provide our calculator with some props, so lets provide some props. We have our progress tracker so let's say amountPossible is equal to 5, and the reason we are coding it like this is so we can use this if we code it in another application, we will most likely not but I want you to get in the habit of building components that you can use in multiple apps. So let's go ahead and say the amountPossible is 5 and the amountEnrolled is equal to this.amountEnrolled.
schedule.js
import React, { Component } from 'react'; import { connect } from 'react-redux'; import Gradient from '../gradient'; import ScheduleCourse from './scheduleCourse'; import ProgressTracker from './progressTracker'; class Schedule extends Component { renderCourses() { const data = this.props.courses return data.map((course, index) => { if(course.enrolled) { return <ScheduleCourse {...course} key={index}/> } }) } render() { return ( <div className="schedule"> <h1 className="schedule__title">My Schedule</h1> { this.renderCourses() } <ProgressTracker amountPossible={5} amountEnrolled={this.amountEnrolled}/> <Gradient/> </div> ) } } function mapStateToProps(state) { return { courses: state.courses } } export default connect(mapStateToProps)(Schedule);
Now we need to make this variable or this is not really going to do anything. Lets say in render this.amountEnrolled = 0 so every time it re-renders its going to set itself back to 0 and then whatever we enroll in a course we're going to increment that by one, so this.amountEnrolled++ so this is going to go up by one every time we enroll in a course. We also want to only allow us to enroll in 5 courses so lets say if course enrolled and this.amountEnrolled doesn't equal 5.
schedule.js
import React, { Component } from 'react'; import { connect } from 'react-redux'; import Gradient from '../gradient'; import ScheduleCourse from './scheduleCourse'; import ProgressTracker from './progressTracker'; class Schedule extends Component { renderCourses() { const data = this.props.courses return data.map((course, index) => { if(course.enrolled && this.amountEnrolled != 5) { this.amountEnrolled++; return <ScheduleCourse {...course} key={index}/> } }) } render() { this.ammountEnrolled = 0 return ( <div className="schedule"> <h1 className="schedule__title">My Schedule</h1> { this.renderCourses() } <ProgressTracker amountPossible={5} amountEnrolled={this.amountEnrolled}/> <Gradient/> </div> ) } } function mapStateToProps(state) { return { courses: state.courses } } export default connect(mapStateToProps)(Schedule);
And this will probably produce a bug which will catch later on down the road after we style everything but it's kind of a bug that would be a lot easier to see once we have everything styled. Okay, so this should produce the functionality let's go into our progressTracker.js and actually calculate it. So let's say return and lets say this.props.amountEnrolled / this.props.amountPossible.
progressTracker.js
import React, { Component } from 'react'; class ProgressTracker extends Component { calculateProgress = function() { return (this.props.amountEnrolled / this.props.amountPossible); }.bind(this); render() { return ( <div className="progress-tracker"> <label className="progress-tracker__label">Progress Tracker</label> <div className="progress-tracker__percentage"> {this.calculateProgress()}% </div> </div> ) } } export default ProgressTracker;
Now, what we're going to have to do is multiply it by 100 because you'll see in schedule we're passing in 5 and it's going to be like 1 2 3 right when we are enrolling in a few so that's basically saying 1/5 is .2 and we don't want to be .2% done we want to be 20% done. So by multiplying this by 100 we have 20%, so lets multiply this by 100 at the end here.
progressTracker.js
import React, { Component } from 'react'; class ProgressTracker extends Component { calculateProgress = function() { return (this.props.amountEnrolled / this.props.amountPossible) * 100; }.bind(this); render() { return ( <div className="progress-tracker"> <label className="progress-tracker__label">Progress Tracker</label> <div className="progress-tracker__percentage"> {this.calculateProgress()}% </div> </div> ) } } export default ProgressTracker;
Okay cool, let's check this out and this should complete it. Right now we are enrolled in no classes lets pull this over and enroll in a few 20%, 40%, 60%, 100%.
Okay sweet, that works our grid is a bit messed up but lets just fix that really quickly. The reason it's only displaying three up here and then the rest are going below is because in our grid we specified only 3 specific rows here so lets say repeat auto-fill 1fr and better yet lets say 75 px, that should make it look a lot better.
schedule.scss
.schedule { display: grid; grid-template-rows: 100px repeat(auto-fill, 75px) [progress-s] 76px [progress-e]; grid-row-gap: 22px; }
That should make it look a lot better. Okay sweet, looks much better.
Okay cool, so this works for the most part. There might be a couple things we need to change, but that gets in the 99% of our functionality and were enrolling in classes and we can only enroll in 5.
So yeah, let's go ahead and finish the functionality section of this course once we commit or code in this video and then we will style everything in the next section to look really beautiful like you see here and it'll be pretty quick.
Let's commit our code, I'll say command + j
to get into the terminal then lets say
Terminal
git status git add . git commit -m "finished functionality with the exdeption of a couple soon to be found bugs" git push origin master git push heroku master
I'll see you in the next set of videos where we will implement all of the styles in our application. I'll see you then