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.
You can get your EmailJS Public key from the Account section of your EmailJS dashboard.
Add theĀ sendEmailĀ function into theĀ BookUserĀ component to send an email to the user containing the booking information whenever the form is submitted.
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