Creating a scheduling app with React, Nodejs and EmailJS 🧨
A scheduling app is a software tool that helps individuals or organizations manage and organize appointments, meetings, and tasks efficiently by providing a centralized platform to schedule, view, and modify schedules.
In this article, you’ll learn how to build a scheduling application that allows you to set your availability and share your profile links to enable others to book an appointment with you. You will also be notified via email when someone schedules an appointment.
Just a quick background about us. Novu is the first open-source notification infrastructure. We basically help to manage all the product notifications. It can be In-App (the bell icon like you have in Facebook – Websockets), Emails, SMSs and so on.
I would be super happy if you could give us a star! And let me also know in the comments ❤️ https://github.com/novuhq/novu
Navigate into the server folder and create a package.json file.
cd server & npm init -y
Install Express, Nodemon, and the CORS library.
npm install express cors nodemon
ExpressJS is a fast, minimalist framework that provides several features for building web applications in Node.js, CORS is a Node.js package that allows communication between different domains, and Nodemon is a Node.js tool that automatically restarts the server after detecting file changes.
Create an index.js file – the entry point to the web server.
touch index.js
Set up a Node.js server using Express.js. The code snippet below returns a JSON object when you visit the http://localhost:4000/api in your browser.
React Router is a JavaScript library that enables us to navigate between pages in a React application, and React Toastify is used to display colourful notifications to the users. React Timezone Select is a simple library that provides various available timezones per location.
Delete the redundant files, such as the logo and the test files from the React app, and update the App.js file to display Hello World as below.
In this section, I’ll walk you through creating the various components required to build the application.
Update the App.js file to render the following components below:
import React from "react";import { BrowserRouter, Routes, Route } from "react-router-dom";//\ud83d\udc47\ud83c\udffb componentimport Dashboard from "./components/Dashboard";import Login from "./components/Login";import Signup from "./components/Signup";import Profile from "./components/Profile";import BookUser from "./components/BookUser";//\ud83d\udc47\ud83c\udffb React-Toastify configurationimport { ToastContainer } from "react-toastify";import "react-toastify/dist/ReactToastify.css";const App = () => { return ( } /> } /> } /> } /> } /> </Routes> </BrowserRouter> </div> );};export default App;
From the code snippet above, I imported the Login, Signup, Dashboard, Profile, and BookUser components. Create a components folder containing the files as done below:
cd clientmkdir componentscd componentstouch Login.js Signup.js Dashboard.js Profile.js BookUser.js
The Login and Signup components are the authentication routes.
The Dashboard component is the homepage displayed to authenticated users – where they can set their availability.
The Profile component displays the availability to the user, and the BookUser component allows others to schedule an appointment with them.
Here, we’ll create a user interface that allows users to set their availability according to their location or preferred timezone. React Timezone Select enables us to select from a list of time zones per location.
Update the Dashboard.js component as done below:
import React, { useState, useEffect } from "react";import TimezoneSelect from "react-timezone-select";import { useNavigate } from "react-router-dom";const Dashboard = () => { const [selectedTimezone, setSelectedTimezone] = useState({}); const navigate = useNavigate(); //\ud83d\udc47\ud83c\udffb Runs when a user sign out const handleLogout = () => { localStorage.removeItem("_id"); localStorage.removeItem("_myEmail"); navigate("/"); }; return ( BookMe</h2> Log out </button> </nav> Select your availability</h2> Pick your timezone</p> </div> </main> </div> );};
The code snippet above displays the component, as shown in the image below. The handleLogout function logs a user out of the application by removing the email and id from the local storage.
Below the time zone selection field, we need to create a group of input fields that allow users to set their availability or working hours for each day.
To do this, create a state within the Dashboard component that holds the schedule for each day.
The Profile component is a simple component that displays the user’s schedule as shown below:
Copy the code below into the Profile.js file. Later in the tutorial, we’ll fetch its data from the server.
import React from "react";import { useParams } from "react-router-dom";const Profile = () => { //\ud83d\udc47\ud83c\udffb The ID is the URL parameter for fetching the user's details. const { id } = useParams(); return ( Hey, nevodavid</h2> Here is your schedule: WAT</p> MON</td> 8:00am</td> 10:00pm</td> </tr> </tbody> </table> </div> </main> );};export default Profile;
This page shows a user’s availability according to the username from the URL and allows people to book a session with the user.
Copy the code below into the BookUser.js component.
import React, { useState } from "react";import { useParams } from "react-router-dom";const BookUser = () => { const [fullName, setFullName] = useState(""); const [email, setEmail] = useState(""); const [message, setMessage] = useState(""); const { user } = useParams(); //\ud83d\udc47\ud83c\udffb logs the user's details to the console const handleSubmit = (e) => { e.preventDefault(); console.log(email, fullName, message); setFullName(""); setMessage(""); }; return ( Book a session with {user}</h2> Full Name</label> setFullName(e.target.value)} /> Email Address</label> setEmail(e.target.value)} /> Any important note? (optional)</label> setMessage(e.target.value)} /> Select your preferred session - GMT+2 Jerusalem </label> SEND</button> </form> </div> );};export default BookUser;
The code snippet above displays a booking form that accepts the client’s full name, email, and message. Later in this tutorial, we’ll improve the component to book a session with a user and send a confirmation email to the user.
Here, I will walk you through fetching the user’s schedules from the server.
Add a GET route on the server that retrieves the user’s data from the database array.
app.get("/schedules/:id", (req, res) => { const { id } = req.params; //\ud83d\udc47\ud83c\udffb filters the array via the ID let result = database.filter((db) => db.id === id); //\ud83d\udc47\ud83c\udffb returns the schedule, time and username if (result.length === 1) { return res.json({ message: "Schedules successfully retrieved!", schedules: result[0].schedule, username: result[0].username, timezone: result[0].timezone, }); } //\ud83d\udc47\ud83c\udffb if user not found return res.json({ error_message: "Sign in again, an error occured..." });});
Create a function within the Profile.js file that sends a request to the GET route when the page is loaded.
In this section, you’ll learn how to send email notifications via EmailJS when clients book an appointment with a user.
EmailJS is a JavaScript library that enables us to send emails via client-side technologies only – without a server. With EmailJS, you can send texts and email templates and add attachments to the emails.
Create a POST route on the server that fetches the user’s data.
app.post("/schedules/:username", (req, res) => { const { username } = req.body; //\ud83d\udc47\ud83c\udffb filter the databse via the username let result = database.filter((db) => db.username === username); if (result.length === 1) { const scheduleArray = result[0].schedule; //\ud83d\udc47\ud83c\udffb return only the selected schedules const filteredArray = scheduleArray.filter((sch) => sch.startTime !== ""); //return the schedules and other information return res.json({ message: "Schedules successfully retrieved!", schedules: filteredArray, timezone: result[0].timezone, receiverEmail: result[0].email, }); } return res.json({ error_message: "User doesn't exist" });
Add a fetchBookingDetails function within the resource.js file.
export function fetchBookingDetails( user, setError, setTimezone, setSchedules, setReceiverEmail) { //...data}
Import the function into the BookUser.js component and call it with its necessary parameters on page load.
Here, I’ll guide you through adding EmailJS to the React.js application and how to send emails to users whenever someone books an appointment with them.
Install EmailJS to the React application by running the code below:
npm install @emailjs/browser
Create an EmailJS account here and add an email service provider to your account.
Add an email template as done in the image below:
The words in curly brackets represent variables that can hold dynamic data.
Import EmailJS into the utils/resource.js file and create a function that sends an email notification to the user.
So far, you’ve learnt how to create a scheduling application that enables users to set their availability and get notified via EmailJS when they have an appointment.
This tutorial walks you through a mini project you can build using React and Node.js. You can improve the application by adding an authentication library and storing the data in a database.
The source code for this tutorial is available here:
If you feel like this article helped you understand WebSockets better! I would be super happy if you could give us a star! And let me also know in the comments ❤️ https://github.com/novuhq/novu