How to build a scheduling and booking app with cloud data storage and real-time updates in Nuxt.js
Tags: nuxt, javascript, tutorial, opensource
Published: 2023-07-04 11:08:45

A reservation and booking system is a software application that allows businesses to manage their bookings and reservations. This can include anything from hotel rooms to restaurant tables to doctor's appointments. Reservation and booking systems can be valuable tools for businesses of all sizes. They can help to improve efficiency, reduce errors, and improve customer satisfaction.

[Appwrite Cloud](https://cloud.appwrite.io/?utm_source=hackmamba&utm_medium=hackmamba-blog) is an extension of the open-source version of Appwrite. It comes with all the services included in the open-source version but now with a fully-managed service and minimum friction. 

This post demonstrates how to build a simple reservation system with [Appwrite Cloud's](https://cloud.appwrite.io/?utm_source=hackmamba&utm_medium=hackmamba-blog) database and real-time updates on bookings and schedules.

## GitHub
The project's GitHub repository can be found [here](https://github.com/Tundesamson26/nuxt-booking-app).

## Prerequisites 
To follow along with this tutorial, you should have a working knowledge of the following:

- Vue, Nuxt.js, and CSS
- An Appwrite cloud account (you can request access to Appwrite Cloud [here](https://appwrite.io/cloud/?utm_source=hackmamba&utm_medium=hackmamba-blog))

## Setting up the project
You need to create a Nuxt.js starter project by navigating to the desired directory and running the command below in your terminal.

```js
npx nuxi@latest init booking-app
```

The command creates a Nuxt.js project called `booking-app`.

Next, you need to install Nuxt.js dependencies by running the command below in your terminal.

```js
npm install
```
Next, go to the project directory and start the development server on `localhost:3000` with the commands below.

```js
cd booking-app && npm run dev
```

## Installing dependencies

**Installing Pink Design**
[Pink Design](https://pink.appwrite.io/?utm_source=hackmamba&utm_medium=hackmamba-blog) is an open-source system from Appwrite used to build consistent and reusable user interfaces. It enhances collaboration, development experience, and accessibility.

To install Pink Design, open the terminal in the project directory and run the following command.

```js
npm install @appwrite.io/pink
```

To use Pink Design in your project, import it into your project's files like this:

```js
import '@appwrite.io/pink';
import '@appwrite.io/pink-icons';
```

**Installing Appwrite**
[Appwrite](https://appwrite.io/?utm_source=hackmamba&utm_medium=hackmamba-blog) is a development platform that provides a powerful API and management console for building backend servers for web and mobile applications. To install it, run the command below:

```js
npm install appwrite
```
## Creating an Appwrite Cloud project

To get started, log into your Appwrite cloud, click the **Create project** button, input `booking-app` as the name, then click **Create**.

![appwrite-create-booking-app tab](https://paper-attachments.dropboxusercontent.com/s_1CC604B8747941C3A5F4C231DDB1151AC72B3202292BBA7149F85CD934F59025_1685948948141_image.png)


**Create a database, collection, and add attributes**
With your project created, you can set up your application database. First, navigate to the **Databases** tab, click the **Create database** button, input `bookings` as the name, and then click **Create**.

![Appwrite database tab](https://paper-attachments.dropboxusercontent.com/s_1CC604B8747941C3A5F4C231DDB1151AC72B3202292BBA7149F85CD934F59025_1685949028312_image.png)


Secondly, you need to create a collection for storing your bookings. To do this, click the **Create collection** button, input `booking_collection` as the name, and then click **Create**.

![Appwrite collections tab](https://paper-attachments.dropboxusercontent.com/s_1CC604B8747941C3A5F4C231DDB1151AC72B3202292BBA7149F85CD934F59025_1685949110192_image.png)


Thirdly, you need to create attributes to represent your database fields. To do this, you need to navigate to the **Attributes** tab and create attributes for each of the values that collect the bookings information, as shown below:

| Attribute key | Attribute type | Size | Required |
| ------------- | -------------- | ---- | -------- |
| **fullName**  | String         | 500  | YES      |
| **message**   | String         | 500  | YES      |
| **date**      | String         | 500  | YES      |
| **time**      | String         | 500  | YES      |

![Appwrite attribute tab](https://paper-attachments.dropboxusercontent.com/s_1CC604B8747941C3A5F4C231DDB1151AC72B3202292BBA7149F85CD934F59025_1685949184740_image.png)


Finally, you need to update your database permission to manage them accordingly. Navigate to the **Settings** tab, scroll to the **Update Permissions** section, select `Any`, mark accordingly, and then click **Update**.

![Appwrite permission tab](https://paper-attachments.dropboxusercontent.com/s_1CC604B8747941C3A5F4C231DDB1151AC72B3202292BBA7149F85CD934F59025_1685949265294_image.png)


After applying the necessary configurations on Appwrite, let's start building the application.

## Integrating Appwrite Cloud into the Nuxt.js project

To integrate Appwrite into the UI, create a `utils/web-init.js` file. The file should look like this.

```js
import { Client } from 'appwrite';
const client = new Client();
client
    .setEndpoint('https://cloud.appwrite.io/v1')
    .setProject('646812a2e22b9fbf08d8');
```
The code above does the following:

- Import the module `Client` from appwrite
- Instantiates the `Client` object
- Uses the client object to set the endpoint and project

## Building the booking interface
Let us create a booking page where users will input their schedule which will be stored in the database. To do this, you will create a `components/BookUser.vue` and add the code below:

{% embed https://gist.github.com/Tundesamson26/dea90ed5e095cd676a50abeef522a772 %}

The gist above achieves the following:

- Imports the Appwrite Pink Design for styling
- Created a form to accept the **name**, **message**, **date**, and available **time** for users to book an appointment
- Added the data to return to the database

Next, import the `components/BookUser.vue` into the `pages/index.vue`, like so:

```js
<template>
  <div>
   <BookUser/>
  </div>
</template>
<script>
import "@appwrite.io/pink"; // optionally, add icons
import "@appwrite.io/pink-icons";
</script>
```

At this point, your booking and scheduling page should look like the below:

![Booking-app UI](https://paper-attachments.dropboxusercontent.com/s_1CC604B8747941C3A5F4C231DDB1151AC72B3202292BBA7149F85CD934F59025_1684690250381_image.png)


**Creating database documents**
Next, you need to add new documents to the database collection. In the `components/BookUser.vue` file, write a `uploadBooking()` function to create the document.

```js
async uploadBooking() {
      if (this.blockedDates.includes(this.date)) {
        alert("This date is blocked for booking");
        return; // Stop the execution of the method
      }
      try {
        await databases
          .createDocument(
            "64681868ceef66544a00",
            "64681913b4c68fd83d28",
            "unique()",
            {
              name: this.name,
              message: this.message,
              date: this.date,
              time: this.time,
            }
          )
        alert("booking sent in");
      } catch (error) {
        console.log(error); // Failure
      }
}
```

In the code block above, the `uploadBooking()` function does the following:

- Creates a new document using Appwrite's `createDocument()` function while passing the collection ID and attribute values as parameters
- Checks if the user includes a particular date blocked by the admin, then stops the booking execution

Make sure to add a click event to the **Submit** button and also prevent the page from reloading, like so:

```html
<div class="u-flex u-main-end u-gap-12">
      <button class="button" type="submit" @click.prevent="uploadBooking">
            Submit
      </button>
 </div>
```

## Building the dashboard interface

This is where the admin user will see the scheduled appointment in real time. In the `page` directory, create a `dashboard.vue` file and paste the following code.

{% embed https://gist.github.com/Tundesamson26/6881ba028cb25a9b15263f510b3abcee %}

This section is a simple table containing all the booking information details: the user's name, message, date, and time. There's also a `props` object for each of these attributes.

## Fetching the bookings

Your page displays the booking information that was entered into the form. With this logic, you want your `upload``Booking``()` function to be responsible for creating the documents to display user booking information.

In the `pages/dashboard.vue` file, you create a `getBookings()` function that gets called when mounted on your app, puts all the details in an object, and pushes it to the bookings array.

```js
methods: {
    async getBookings() {
      try {
        let bookingData = await databases.listDocuments(
          "64681868ceef66544a00",
          "64681913b4c68fd83d28"
        );
        console.log(bookingData);
        this.bookings = bookingData;
        console.log(response); // Success);
      } catch (error) {
        console.log(error, "error");
      }
    },
}
```

Every time the page reloads or when changes occur in the database, you want to fetch all the booking details in real time. To do that, call the `getBookings()` function on the mounted method like so:

```js
mounted() {
    this.getBookings();
    if (account.get !== null) {
      try {
        client.subscribe("documents", (response) => {
          console.log(response);
          this.getBookings();
        });
      } catch (error) {
        console.log(error, "error");
      }
    }
},
```
## Displaying the bookings

To display the bookings, all you have to do is loop over the bookings array and pass in all the data as props, like so:

```html
<tr
    class="table-row"
    v-for="booking in bookings.documents"
    :key="booking.$id"
>
<!-- table data goes here... -->
</tr>
```
Fill out the booking form, and on the dashboard, the admin user sees the booking information in real-time, like so:

{% embed
https://www.loom.com/share/54ef15c829f14b95af456ebb310792fc %}

![Appwrite documents tab](https://paper-attachments.dropboxusercontent.com/s_1CC604B8747941C3A5F4C231DDB1151AC72B3202292BBA7149F85CD934F59025_1685950274214_image.png)

## Conclusion
This article discussed using [Appwrite](https://appwrite.io/cloud?utm_source=hackmamba&utm_medium=hackmamba-blog) [Cloud's](https://appwrite.io/cloud?utm_source=hackmamba&utm_medium=hackmamba-blog) database system to store data and display the data in real-time for a booking and scheduling app in Nuxt 3 app.

## Resources
- [Appwrite](https://appwrite.io/?utm_source=hackmamba&utm_medium=hackmamba-blog)
- [Appwrite Cloud](https://appwrite.io/cloud?utm_source=hackmamba&utm_medium=hackmamba-blog)
- [Appwrite](https://appwrite.io/docs/realtime)['](https://appwrite.io/docs/realtime)[s](https://appwrite.io/docs/realtime) [Real-time](https://appwrite.io/docs/realtime?utm_source=hackmamba&utm_medium=hackmamba-blog)
- [Appwrite Pink Design](https://pink.appwrite.io/?utm_source=hackmamba&utm_medium=hackmamba-blog)