Now it’s time to showcase your education and skills! We will display your college degrees, and your relevant skills within your field. Since this is based on software development, we will show programming languages, database management systems, front-end and back-end frameworks.

  1. In the Models folder, create a new class called School.cs. Add the following code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace PersonalResume.Models
{
    public class School
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Logo { get; set; }
        public string Major { get; set; }
        public string Degree { get; set; }
        public string StartDate { get; set; }
        public string EndDate { get; set; }
        public string Location { get; set; }
    }
}

2. Add another model class called Skill.cs.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace PersonalResume.Models
{
    public class Skill
    {
        public int Id { get; set; }
        public string Category { get; set; }
        public string[] SkillsList { get; set; }
    }
}

3. Add one more model class called Education.cs. This will contain lists of the objects we just created.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace PersonalResume.Models
{
    public class Education
    {
        public IEnumerable<School> SchoolList { get; set; }
        public IEnumerable<Skill> SkillList { get; set; }
    }
}

4. Create a new folder in images called schools. Put your school image in there.

5. In your Data folder, create a new JSON file called schools.json. Update the properties with your college history, starting with the most recent. If you don’t have the degree yet, just leave the value as “”. ex: “Degree”: “”.

[
  {
    "Id": 1,
    "Name": "University of Maryland, Baltimore County",
    "Logo": "umbc.png",
    "Major": "Computer Science",
    "Degree": "Master of Science",
    "StartDate": "Jan 2017",
    "EndDate": "Dec 2019",
    "Location": "Baltimore, MD"
  },
  {
    "Id": 2,
    "Name": "University of Maryland, Baltimore County",
    "Logo": "umbc.png",
    "Major": "Computer Science",
    "Degree": "Bachelor of Science",
    "StartDate": "Aug 2012",
    "EndDate": "Dec 2016",
    "Location": "Baltimore, MD"
  }
]

6. In your Data folder, add skills.json. This can be updated to be relevant to your skills. Change the categories to whatever you like. (Expert skills, moderate, novice, Microsoft software, etc).

[
  {
    "Id": 1,
    "Category": "Programming Languages",
    "SkillsList": [
      "C# (.NET, MVC)",
      "HTML",
      "CSS3",
      ".LESS",
      "JavaScript",
      "Java",
      "SQL",
      "JSON",
      "XML"
    ]
  },
  {
    "Id": 2,
    "category": "JavaScript Frameworks",
    "skillsList": [
      "React.js",
      "jQuery",
      "AngularJS"
    ]
  },
  {
    "Id": 3,
    "category": "Cloud Service",
    "skillsList": [
      "AWS EC2",
      "Bamboo",
      "Heroku"
    ]
  },
  {
    "Id": 4,
    "category": "Database Management",
    "skillsList": [
      "SQL Server",
      "MongoDB"
    ]
  }

]

7. Add a new Controller in Controllers called EducationController and add the following code. This will deserialize schools.json and skills.json into a Education object. Test the endpoint to make sure it works.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using PersonalResume.Models;

namespace PersonalResume.Controllers
{

    [Route("api/education")]
    [ApiController]
    public class EducationController : ControllerBase
    {
        public Education GetEducation()
        {
            var schools = JsonConvert.DeserializeObject<IEnumerable<School>>(System.IO.File.ReadAllText("./Data/schools.json"));
            var skills = JsonConvert.DeserializeObject<IEnumerable<Skill>>(System.IO.File.ReadAllText("./Data/skills.json"));
            return new Education
            {
                SchoolList = schools,
                SkillList = skills
            };
        }
    }
}

8. Add Education.js and Education.css in the components folder. This component is similar to Job, which will call api/education to get the Education object. Then we will loop through Schools and Skills and display their component in separate cards. We will build those components in the next step.

import React, { Component } from 'react';
import {
    Row, Col, Card, CardBody, Spinner
} from 'reactstrap';
import School from './subcomponents/School';
import Skill from './subcomponents/Skill';
import './Education.css';

export class Education extends Component {
    displayName = Education.name;

    constructor(props) {
        super(props);
        this.state = {
            schools: [],
            skills: [],
            isLoading: true
        }
    }

    componentDidMount() {
        fetch('api/education')
            .then(response => response.json())
            .then(data => {
                this.setState({ schools: data.schoolList, skills: data.skillList, isLoading: false })
            })
    }

    render() {
        if (this.state.isLoading) {
            return (<div className="spinner-border image-center" style={{ width: '5rem', height: '5rem' }}> </div>);
        }
        else {
            return (
                <div className="edu">
                    <div className="edu-section">
                        <h1 className="text-center">Education</h1>
                        <hr></hr>
                        <Row>
                            {this.state.schools.map(school =>
                                <School key={school.id} school={school} />
                            )}
                        </Row>
                    </div>
                    <div className="edu-section">
                        <h1 className="text-center">Skills</h1>
                        <hr></hr>
                        <Row>
                            <Col md={12}>
                                <Card className="skills-card">
                                    <CardBody>
                                        {this.state.skills.map(skill =>
                                            <Skill key={skill.id} skill={skill} />
                                        )}
                                    </CardBody>
                                </Card>
                            </Col>
                        </Row>
                    </div>
                </div>
            );
        }
    }
}; 
.edu-section {
    padding-top: 10px;
}

label {
    font-weight: bold;
}

9. In the components>subcomponents folder, add School.js, Skill.js and School.css. These are functional components that take in props as a parameter.

import React, { Component } from 'react';
import './School.css';
import {
    Row, Col, Card, CardImg, CardText, CardBody,
    CardTitle, CardSubtitle, Button
} from 'reactstrap';

function School(props) {
    //checks if you have a degree, and will display the degree, major or just the major.
    function hasDegree(school) {
        if (school.degree == "") {
            return <CardSubtitle><span>{school.major}</ span></CardSubtitle>
        }
        return <CardSubtitle>{school.degree}, <span>{school.major}</span></CardSubtitle>
    }

    const school = props.school;
    return (
        <Col md={6}>
            <Card className="school-card">
                <CardBody>
                    <Row>
                        <Col md={9} sm={12} className="school-info">
                            <CardTitle className="job-title">{school.name}</CardTitle>
                            {hasDegree(school)}
                            <CardText>{school.startDate} - {school.endDate}</CardText>
                            <CardText className="job-location">{school.location}</CardText>
                        </Col>
                        <Col md={3} sm={12}>
                            <CardImg className="school-logo" top width="100%" src={require('../../images/schools/' + school.logo)} />
                        </Col>
                    </Row>
                </CardBody>
            </Card>
        </Col>
    );
}

export default School;

import React, { Component } from 'react';
import {
    Row, Col, Card, CardImg, CardText, CardBody,
    CardTitle, CardSubtitle, Button
} from 'reactstrap';
import './School.css';

function Skill(props) {

    const skill = props.skill;
    const listLength = skill.skillsList.length;
    return (
        <div className="skills">
            <Row>
                <Col md={3}>
                    <label>{skill.category}:</label>
                </Col>
                <Col md={9}>
                    <CardText>
                        {skill.skillsList.map((s, index) =>
                            listLength === index + 1 ? s : s + ', '
                        )}
                    </CardText>
                </Col>
            </Row>
        </div>
    );
}

export default Skill;

@media only screen and (min-width: 768px) {
    .school-logo {
        width: 150px;
        float: right;
    }
}

@media only screen and (max-width: 767px) {
    .school-logo {
        width: 50%;
        margin-left: auto;
        margin-right: auto;
        display: block;
    }

    .school-info {
        text-align: center;
    }

    .skills {
        text-align: center;
    }
}

@media only screen and (max-width: 767px) and (orientation: portrait) {
    .school-logo {
        width: 50%;
        margin-left: auto;
        margin-right: auto;
        display: block;
    }

    .school-info {
        text-align: center;
    }
}

10. In NavMenu.js, update the following line to include Education.

import React, { Component } from 'react';
import { Collapse, Container, Navbar, NavbarBrand, NavbarToggler, NavItem, NavLink } from 'reactstrap';
import { Link } from 'react-router-dom';
import './NavMenu.css';
import { Jobs } from './Jobs';

export class NavMenu extends Component {
  static displayName = NavMenu.name;

  constructor (props) {
    super(props);

    this.toggleNavbar = this.toggleNavbar.bind(this);
    this.state = {
      collapsed: true
    };
  }

  toggleNavbar () {
    this.setState({
      collapsed: !this.state.collapsed
    });
  }

  render () {
    return (
      <header>
        <Navbar className="navbar-expand-sm navbar-toggleable-sm ng-white border-bottom box-shadow mb-3" light>
          <Container>
            <NavbarBrand tag={Link} to="/">PersonalResume</NavbarBrand>
            <NavbarToggler onClick={this.toggleNavbar} className="mr-2" />
            <Collapse className="d-sm-inline-flex flex-sm-row-reverse" isOpen={!this.state.collapsed} navbar>
              <ul className="navbar-nav flex-grow">
                <NavItem>
                  <NavLink tag={Link} className="text-dark" to="/jobs">Jobs</NavLink>
                </NavItem>
                <NavItem>
                  <NavLink tag={Link} className="text-dark" to="/education">Education</NavLink>
                </NavItem>
                <NavItem>
                  <NavLink tag={Link} className="text-dark" to="/fetch-data">Fetch data</NavLink>
                </NavItem>
              </ul>
            </Collapse>
          </Container>
        </Navbar>
      </header>
    );
  }
}

11. Update App.js with the following lines. This will allow the Education component to render at /education.

import React, { Component } from 'react';
import { Route } from 'react-router';
import { Layout } from './components/Layout';
import { Home } from './components/Home';
import { FetchData } from './components/FetchData';
import { Jobs } from './components/Jobs';
import { Education } from './components/Education';

import './custom.css'

export default class App extends Component {
  static displayName = App.name;

  render () {
    return (
      <Layout>
        <Route exact path='/' component={Jobs} />
        <Route path='/jobs' component={Jobs} />
        <Route path='/education' component={Education} />
        <Route path='/fetch-data' component={FetchData} />
      </Layout>
    );
  }
}

Start the application and verify it works as expected. Feel free to leave a comment if there are any issues or questions