Author: Dawid Adach
1. Build the app
index.js
file and paste the following code into it:
import React, { Component } from "react";
import ReactDOM from "react-dom";
import '@fortawesome/fontawesome-free/css/all.min.css';
import "bootstrap-css-only/css/bootstrap.min.css";
import "mdbreact/dist/css/mdb.css";
import { MDBBtn, MDBInput, MDBModal, MDBModalBody, MDBModalHeader, MDBModalFooter, MDBIcon, MDBBadge, MDBContainer, MDBRow, MDBCol} from "mdbreact";
import "./index.css";
class App extends Component {
constructor(props) {
super(props);
this.state = {
modal: false,
events: [
{
id: 1,
time: "10:00",
title: "Breakfast with Simon",
location: "Lounge Caffe",
description: "Discuss Q3 targets"
},
{
id: 2,
time: "10:30",
title: "Daily Standup Meeting (recurring)",
location: "Warsaw Spire Office"
},
{ id: 3, time: "11:00", title: "Call with HRs" },
{
id: 4,
time: "12:00",
title: "Lunch with Timmoty",
location: "Canteen",
description:
"Project evalutation ile declaring a variable and using an if statement is a fine way to conditionally render a component, sometimes you might want to use a"
}
]
};
}
addEvent = () => {
var newArray = [...this.state.events];
newArray.push({
id: newArray.length ? newArray[newArray.length - 1].id + 1 : 1,
time: this.state.time,
title: this.state.title,
location: this.state.location,
description: this.state.description
});
this.setState({ events: newArray });
this.setState({
time: "",
title: "",
location: "",
description: ""
});
};
handleInputChange = inputName => value => {
const nextValue = value;
this.setState({
[inputName]: nextValue
});
};
handleDelete = eventId => {
const events = this.state.events.filter(e => e.id !== eventId);
this.setState({ events });
};
toggleModal = () => {
this.setState({
modal: !this.state.modal
});
};
render() {
return (
<React.Fragment>
<MDBContainer>
<MDBRow>
<MDBCol md="9" className="mb-r">
<h2 className="text-uppercase my-3">Today:</h2>
<div id="events">
{this.state.events.map(event => (
<Event
key={event.id}
id={event.id}
time={event.time}
title={event.title}
location={event.location}
description={event.description}
onDelete={this.handleDelete}
/>
))}
</div>
<MDBRow className="mb-4">
<MDBCol xl="3" md="6" className="mx-auto text-center">
<MDBBtn color="info" rounded onClick={this.toggleModal}>
Add Event
</MDBBtn>
</MDBCol>
</MDBRow>
</MDBCol>
<MDBCol md="3">
<h3 className="text-uppercase my-3">Schedule</h3>
<h6 className="my-3">
It is going to be busy that today. You have{" "}
<b>{this.state.events.length} events </b> today.
</h6>
<h1 className="my-3">
<MDBRow>
<MDBCol xs="3" className="text-center">
<MDBIcon icon="sun" fixed />
</MDBCol>
<MDBCol xs="9">Sunny</MDBCol>
</MDBRow>
<MDBRow>
<MDBCol xs="3" className="text-center">
<MDBIcon icon="thermometer-three-quarters" fixed />
</MDBCol>
<MDBCol xs="9">23°C</MDBCol>
</MDBRow>
</h1>
<p>
Don't forget your sunglasses. Today will dry and sunny, becoming
warm in the afternoon with temperatures of between 20 and 25
degrees.
</p>
</MDBCol>
</MDBRow>
</MDBContainer>
<MDBModal isOpen={this.state.modal} toggle={this.toggleModal}>
<MDBModalHeader
className="text-center"
titleClass="w-100 font-weight-bold"
toggle={this.toggleModal}
>
Add new event
</MDBModalHeader>
<MDBModalBody>
<form className="mx-3 grey-text">
<MDBInput
name="time"
label="Time"
icon="clock"
hint="12:30"
group
type="text"
getValue={this.handleInputChange("time")}
/>
<MDBInput
name="title"
label="Title"
icon="edit"
hint="Briefing"
group
type="text"
getValue={this.handleInputChange("title")}
/>
<MDBInput
name="location"
label="Location (optional)"
icon="map"
group
type="text"
getValue={this.handleInputChange("location")}
/>
<MDBInput
name="description"
label="Description (optional)"
icon="sticky-note"
group
type="textarea"
getValue={this.handleInputChange("description")}
/>
</form>
</MDBModalBody>
<MDBModalFooter className="justify-content-center">
<MDBBtn
color="info"
onClick={() => {
this.toggleModal();
this.addEvent();
}}
>
Add
</MDBBtn>
</MDBModalFooter>
</MDBModal>
</React.Fragment>
);
}
}
class Event extends Component {
render() {
return (
<React.Fragment>
<div className="media mt-1">
<h3 className="h3-responsive font-weight-bold mr-3">
{this.props.time}
</h3>
<div className="media-body mb-3 mb-lg-3">
<MDBBadge
color="danger"
className="ml-2 float-right"
onClick={() => this.props.onDelete(this.props.id)}
>
-
</MDBBadge>
<h6 className="mt-0 font-weight-bold">{this.props.title} </h6>{" "}
<hr className="hr-bold my-2" />
{this.props.location && (
<React.Fragment>
<p className="font-smaller mb-0">
<MDBIcon icon="location-arrow" /> {this.props.location}
</p>
</React.Fragment>
)}
</div>
</div>
{this.props.description && (
<p className="p-2 mb-4 blue-grey lighten-5 blue-grey lighten-5">
{this.props.description}
</p>
)}
</React.Fragment>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));

2. Run the app

3. Responsiveness

4. Code review
4.1 Imports
import React, { Component } from "react";
import ReactDOM from "react-dom";
import '@fortawesome/fontawesome-free/css/all.min.css';
import "bootstrap-css-only/css/bootstrap.min.css";
import "mdbreact/dist/css/mdb.css";
import { MDBBtn, MDBInput, MDBModal, MDBModalBody, MDBModalHeader, MDBModalFooter, MDBIcon, MDBBadge, MDBContainer, MDBRow, MDBCol } from "mdbreact";
4.2 App class
class App extends Component {
constructor(props) { ... }
toggleModal = () => { ... };
handleInputChange = inputName => value => { ... };
handleDelete = eventId => { ... };
addEvent = () => { ... };
render() {
return ([..);
}
}
4.2.1 constructor()— without going into details I want you to remember that whenever React renders (is mounting) some class (components) it executes a few functions in a certain order. For now, just remember that constructor() is called before the render() function. For that reason we have placed here the initial state of our component - status of the modal (false = not visible) as well as an array containing the initial list of the events.
Mounting phase
These methods are called in the following order when an instance of a component is being created and inserted into the DOM:
constructor() getDerivedStateFromProps() render() componentDidMount()

<div id="events">
{this.state.events.map(event => (
<Event
key={event.id}
id={event.id}
time={event.time}
subject={event.subject}
location={event.location}
description={event.description}
onDelete={this.handleDelete}
/>
))}
</div>
The second column contains information on how many events we have in our agenda. It also contains a hard coded weather forecast. In one of the future lessons we will learn how to call a real API and display real data.
The last element located outside the container is our modal. This is the small window which becomes visible once you click the "ADD EVENT" button.
5. Event component
The third part is a definition of our item component. I'll draw a chart to help you visualize the structure of our application:

6. ReactDOM.render()
Previous lesson Download Next lesson
Spread the word:
