We are going to begin working on individual components. Components are a section of your application and can be re-used across your application. Most of the components we create will require us to create a Controller, Model, Component class, and a Sub component. First, we will create an About component. This will always display at the top of the page, and will contain information about you, such as name, description, location, title, linkedin and email links. Here’s what it will look like!

Let’s begin by installing a few packages using npm.

1. Open up your package manager by going to Tools > Nuget Package Manager > Package Manager Console.

2. Type cd (Your Project Name)\ClientApp .You can install npm dependencies here. We are going to install react-strap. React-Strap allows you to use the Bootstrap framework as react components. Enter this command:

npm install --save reactstrap react react-dom

3. Open your index.html file. We will be making 1 change here to add FontAwesome. This is for using icons from fontawesome.com. Add the link tag on line 16.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="#000000">
    <base href="%PUBLIC_URL%/" />
    <!--
      manifest.json provides metadata used when your web app is added to the
      homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">

    <!-- Add this line!-->
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">

    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>PersonalResume</title>
</head>
  <body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  </body>
</html>

Let’s begin building our component!

4. Add a Models folder in your project, this can be at the root level. We will store data objects in here. Create a class called About.cs.

5. Add the following code. This is the object that will map to the JSON file in the next step. NOTE: When you copy and paste C# code, remember to update your namespace. It should be your {project name}.Models

using System;

namespace PersonalResume.Models
{
    public class About
    {
        public String Name { get; set; }
        public String Title { get; set; }
        public String Location { get; set; }
        public String Description { get; set; }
    }
}

6. Create a new folder called Data and add a new JSON file called about.json. This will contain our data that the API will retrieve, basically our database. Update the property values to whatever you like.

{
  "Name": "George K",
  "Title": "Software Engineer",
  "Location": "Baltimore, MD",
  "Description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Faucibus turpis in eu mi bibendum neque egestas."
}


7. Right click the Controllers folder and click Add > Controller. Select API Controller – Empty, name this class AboutController.cs.

8. Add the following code to AboutController.cs. This will deserialize the JSON file into the About object we created. This will return it at the endpoint api/about. You can test this by running your application and testing directly in the browser, or in Postman.

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

namespace PersonalResume.Controllers
{
    [ApiController]
    [Route("api/about")]
    public class AboutController
    {
        [HttpGet]
        public About GetAboutInfo()
        {
            //Reads text from about.json
            string jsonText = System.IO.File.ReadAllText("./Data/about.json");
            //Deserializes into About object
            return JsonConvert.DeserializeObject<About>(jsonText);
        }
    }
}

7. We will be using images throughout this site, create a new folder called images in the ClientApp > src folder. Create another folder in images called about for organization. Put a picture of yourself here!


8. Time to add the About React component. In ClientApp > src > components, add a new file called About.js and add the following code. Update the image name on line 3 to the image you created earlier. I left comments in this class to give high level descriptions of each part.

import React, { Component } from 'react';
//Update the name for this logo.
import logo from '../images/about/default-avatar.png';
import {
    Row, Col, Card, CardImg, CardText, CardBody,
    CardTitle, CardSubtitle, Button
} from 'reactstrap';

//export class component to use in other components
export class About extends Component {
    displayName = About.name

    //Constructor method
    //We update the state object with the properties from our About object. These are empty strings for now until
    //we pull data from the API
    constructor(props) {
        super(props);
        this.state = {
            name: "",
            title: "",
            location: "",
            description: ""
        }
    }

    //This method is triggered when the About component "mounts", meaning it's available to the DOM.
    //fetch will call the API endpoint we created in the previous steps
    //data contains our data from about.json. Each property in the State object is loaded with this data.
    componentDidMount() {
        fetch('api/about')
            .then(response => response.json())
            .then(data => {
                this.setState({
                    name: data.name,
                    title: data.title,
                    location: data.location,
                    description: data.description
                })
            })
    }

    //render is required in the class Component. This will load JSX code on the DOM. 
    //Row and Col is basic bootstrap, it's just using as a component in React instead of your typical css class.
    //Here we are adding our About information. As a bonus, we are adding icons and links for linkedin, github, and email.
    render() {
        return (
            <div style={{ padding: "15px"}}>
                <Row>
                    <Col md={2}>
                        <img style={{ height: "100px" }} src={logo} />
                    </Col>
                    <Col md={3} className="center-mobile-text">
                        <div >
                            <h5>{this.state.name}</h5>
                            <p>{this.state.location}</p>
                        </div>
                        <a style={{ color: "#007bb5" }} target="_blank" href="https://www.linkedin.com">
                            <span className="fa-stack fa-lg">
                                <i className="fas fa-circle fa-stack-2x"></i>
                                <i className="fab fa-linkedin-in fa-stack-1x fa-inverse"></i>
                            </span>
                        </a>
                        <a style={{ color: "black" }} target="_blank" href="https://github.com/">
                            <span className="fa-stack fa-lg">
                                <i className="fas fa-circle fa-stack-2x"></i>
                                <i className="fab fa-github fa-stack-1x fa-inverse"></i>
                            </span>
                        </a>
                        <a style={{ color: "red" }} target="_blank" href="mailto:GeorgeK@gmail.com">
                            <span className="fa-stack fa-lg">
                                <i className="fas fa-circle fa-stack-2x"></i>
                                <i className="fas fa-envelope fa-stack-1x fa-inverse"></i>
                            </span>
                        </a>
                    </Col>
                    <Col md={7}>
                        <p className="textStyle">{this.state.description}</p>
                    </Col>
                </Row>
            </div>
        )
    }
};

9. We are almost done with this component. We need to add our fontawesome icons and links. We will add anchor tags that will contains links to Email, LinkedIn and Github! If you don’t have all 3, that’s fine, just remove <a></a> and it’s content. If you don’t want to provide any links, you can skip this step.

import React, { Component } from 'react';
//Update the name for this logo.
import logo from '../images/about/default-avatar.png';
import {
    Row, Col, Card, CardImg, CardText, CardBody,
    CardTitle, CardSubtitle, Button
} from 'reactstrap';

//export class component to use in other components
export class About extends Component {
    displayName = About.name

    //Constructor method
    //We update the state object with the properties from our About object. These are empty strings for now until
    //we pull data from the API
    constructor(props) {
        super(props);
        this.state = {
            name: "",
            title: "",
            location: "",
            description: ""
        }
    }

    //This method is triggered when the About component "mounts", meaning it's available to the DOM.
    //fetch will call the API endpoint we created in the previous steps
    //data contains our data from about.json. Each property in the State object is loaded with this data.
    componentDidMount() {
        fetch('api/about')
            .then(response => response.json())
            .then(data => {
                this.setState({
                    name: data.name,
                    title: data.title,
                    location: data.location,
                    description: data.description
                })
            })
    }

    //render is required in the class Component. This will load JSX code on the DOM. 
    //Row and Col is basic bootstrap, it's just using as a component in React instead of your typical css class.
    //Here we are adding our About information. As a bonus, we are adding icons and links for linkedin, github, and email.
    render() {
        return (
            <div className="basic-info">
                <Row>
                    <Col md={2}>
                        <img style={{ height: "100px" }} src={logo} />
                    </Col>
                    <Col md={3} className="center-mobile-text">
                        <div >
                            <h5>{this.state.name}</h5>
                            <p>{this.state.location}</p>
                        </div>
                        <a style={{ color: "#007bb5" }} target="_blank" href="https://www.linkedin.com">
                            <span className="fa-stack fa-lg">
                                <i className="fas fa-circle fa-stack-2x"></i>
                                <i className="fab fa-linkedin-in fa-stack-1x fa-inverse"></i>
                            </span>
                        </a>
                        <a style={{ color: "black" }} target="_blank" href="https://github.com/">
                            <span className="fa-stack fa-lg">
                                <i className="fas fa-circle fa-stack-2x"></i>
                                <i className="fab fa-github fa-stack-1x fa-inverse"></i>
                            </span>
                        </a>
                        <a style={{ color: "red" }} target="_blank" href="mailto:GeorgeK@gmail.com">
                            <span className="fa-stack fa-lg">
                                <i className="fas fa-circle fa-stack-2x"></i>
                                <i className="fas fa-envelope fa-stack-1x fa-inverse"></i>
                            </span>
                        </a>
                    </Col>
                    <Col md={7}>
                        <p className="textStyle">{this.state.description}</p>
                    </Col>
                </Row>
            </div>
        )
    }
};

10. Your web application should look like this. If you have any issues or questions please comment below. Next we will create the Jobs component.