web3 tutorial [08/10] - material-ui: building the calendar interface

by parttimelarry

What is Material UI?

One of the benefits of using React is its ecosystem of well designed component libraries. These include Material UI, React Bootstrap, Semantic UI, and Chakra UI, among others. These component libraries include widgets for common use cases like icons, buttons, sliders, date and time pickers, and more.

Creating a full calendar and scheduling component with date and time pickers is an entire project on its own. Rather than building this from scratch, we will integrate an existing Calendar component. For our project, we will integrate React Scheduler, a component inspired by Google Calendar.

React Scheduler

To get started, we will consult the React Scheduler documentation. We need to install the appropriate packages with npm. Let’s open a terminal and make sure we are in the frontend/ directory of our proejct. Enter the following command to install the react-scheduler component and Material UI dependencies.

npm install --save @devexpress/dx-react-core @devexpress/dx-react-scheduler @devexpress/dx-react-scheduler-material-ui

Once the packages have been installed, let’s open the components/Calendar.js file that we created in the last section. Remember we only created a simple placeholder for a calendar. Let’s import the React Scheduler components and add them to our Calendar component using the code below:

/* Scheduling Component */
import { ViewState, EditingState, IntegratedEditing } from '@devexpress/dx-react-scheduler';
import { Scheduler, WeekView, Appointments, AppointmentForm } from '@devexpress/dx-react-scheduler-material-ui';

const Calendar = () => {
    return (<div id="calendar">
      <Scheduler>
        <ViewState />
        <EditingState  />
        <IntegratedEditing />
        <WeekView  />
        <Appointments />
        <AppointmentForm />
      </Scheduler>
    </div>);
}

export default Calendar;

All of the components we imported are documented in the Getting Started guide if you want to know the details of each component. The key point here is that React Scheduler provides reuseable components like and that can be customized based on our application’s needs.

Let’s take a look at our webapp and see how it looks so far:

Calendar

Already looks pretty good! We have a weekly calendar view and we can click it and see an appointment form. We just need to figure out how to customize it and integrate it with our smart contract.

Calendar

Customizing the Week View with React Props

Customization of a React component is done via props. Props let us pass information to a component in a manner similar to how we use attributes and values in HTML. Each component accepts certain props that let us customize its behavior.

The first thing we will customize is the hours shown on the calendar. I personally hate 8AM meetings, so we will simply remove these from the calendar. We also don’t want to meet after 7PM because we have a life. The WeekView component is documented here and provides the props startDayHour and endDayHour, which let us define the start and end hours of each day. We will use 9 for the startDayHour and 19 for the endDayHour:

<WeekView startDayHour={9} endDayHour={19}/>

Rendering Mock Appointment Data

Next we want to see how appointments look on our calendar and make sure this functionality works. Before we connect the calendar to the blockchain, let’s add some sample mock data. This will prepare us for how we need to transform and structure the blockchain data when we hook it up in the next section.

In the example on the React Scheduler site, the documentation provides a sample data structure to render an appointment:

const schedulerData = [
  { startDate: '2018-11-01T09:45', endDate: '2018-11-01T11:00', title: 'Meeting' },
  { startDate: '2018-11-01T12:00', endDate: '2018-11-01T13:30', title: 'Go to a gym' },
];

Let’s modify this slightly to reflect the current week and year and see how it looks on the calendar.

const schedulerData = [
  { startDate: '2022-02-24T09:45', endDate: '2022-02-24T11:00', title: 'Dogecoin Integration' },
  { startDate: '2022-02-25T12:00', endDate: '2022-02-25T13:30', title: 'Podcast appearance' },
];

To connect it to the Scheduler, we pass schedulerData to the data prop like so:

<Scheduler data={schedulerData}>

Let’s see how it looks on the webapp:

Calendar Customized

Beautiful. We now see some example appointments on our calendar and will swap these out with real data that is fetched from the blockchain in the next section.

Callback Functions

The last component we will customize in this Appointment Editor. We want to capture the data that is submitted in the form so that we can submit it to our smart contract.

Calendar Callback Function

According to documentation, we can pass a callback function to the onCommitChanges prop. Let’s define a function called saveAppointment that will be called when the save button is clicked on the appointment form.

For now, let’s just log the data that is saved to the console and observe the Developer Tools in Chrome. This is just a placeholder to make sure this logic is fired when the form is saved. We’ll fill in the blockchain logic in the next section.

const saveAppointment = (data) => {
    console.log('committing changes');
    console.log(data);
}

To connect this callback function to the EditingState component, we just pass it in to the onCommitChanges prop like so:

<EditingState onCommitChanges={saveAppointment} />

If we save an appointment while the JavaScript console is open, we can see our function is called and an object is submitted that describes our form submission. It has an “added” attribute, a startDate, an endDate, a title, and notes.

Calendar Callback Function

Great progress in this section! It’s really coming together. Your Calendar.js should now closely match the code below. In the next section, we will connect this UI to our smart contract and use data from the blockchain.

/* Scheduling Component */
import { ViewState, EditingState, IntegratedEditing } from '@devexpress/dx-react-scheduler';
import { Scheduler, WeekView, Appointments, AppointmentForm } from '@devexpress/dx-react-scheduler-material-ui';

const schedulerData = [
    { startDate: '2022-02-24T09:45', endDate: '2022-02-24T11:00', title: 'Dogecoin Integration' },
    { startDate: '2022-02-25T12:00', endDate: '2022-02-25T13:30', title: 'Podcast Appearance' },
];

const Calendar = () => {

    const saveAppointment = (data) => {
        console.log('committing changes');
        console.log(data);
    }

    return (<div id="calendar">
      <Scheduler data={schedulerData}>
        <ViewState />
        <EditingState onCommitChanges={saveAppointment} />
        <IntegratedEditing />
        <WeekView startDayHour={9} endDayHour={19}/>
        <Appointments />
        <AppointmentForm />
      </Scheduler>
    </div>);
}

export default Calendar;