Reader small image

You're reading from  Building Real-World Web Applications with Vue.js 3

Product typeBook
Published inJan 2024
Reading LevelIntermediate
PublisherPackt
ISBN-139781837630394
Edition1st Edition
Languages
Tools
Right arrow
Author (1)
Joran Quinten
Joran Quinten
author image
Joran Quinten

Joran Quinten's passion involves getting people to love technology and getting technology to play nice. With over a decade of experience in developing and designing software, he has built up a broad background in development and architecture. He loves sharing knowledge and has been invited to speak at several tech events. Joran graduated from Fontys University of Applied Sciences, Eindhoven in 2010. Currently, he works for Jumbo Supermarkten, a national grocery chain where he is the technical lead of the design system team and acts as an ambassador for the tech department. He is passionate about mentoring and coaching junior developers. Joran lives close to Eindhoven with his wife, son and daughter.
Read more about Joran Quinten

Right arrow

Creating a Fitness Tracker with Data Visualization

Up until this point, we’ve relied on stateless apps or storing the state on the users’ browser. In this chapter, we’ll cover using a database to store data in a centralized place, and we’ll learn how to modify and read from the data source. We’ll use the opportunity to incorporate some data visualizations as well, using a third-party library.

While we’re using a database and have to set up tables, this is by no means a guide to production-ready database configuration and management. I suggest brushing up on those skills in different ways. It does serve as a valuable prototype to familiarize yourself with patterns concerning database handling.

Again, we’ll build upon the knowledge we’ve acquired so far, and we’ll incorporate composables, a store, and a component library to build our product.

In this chapter, we’ll cover the following topics:

  • Creating...

Technical requirements

There’s some overlap in requirements from the previous chapter. We’ll make use of Vuetify (https://vuetifyjs.com/en/) and Pinia (https://pinia.vuejs.org/). For storing data, we’ll make use of Supabase (https://supabase.com/), which is an open source database provider with built-in authentication. For the database, I’ve prepared a script to create databases and another one to add example data.

Here’s the GitHub link: https://github.com/PacktPublishing/Building-Real-world-Web-Applications-with-Vue.js-3/tree/main/06.fitness.

We’ll cover those steps during the chapter. Lastly, for data visualization, we’ll install and use vue-chartjs (https://vue-chartjs.org/), which is a Vue-compatible wrapper for the chart.js (https://www.chartjs.org/) library.

Creating a client

In order to start our project, we’ll use the Vuetify installer, just as we did in the last chapter. Here’s the command for that:

npm create vuetify

Choose vue-fitness-tracker as the project name and select these options, as shown in the following screenshot:

Figure 6.1 – Setting up the Vuetify project

Figure 6.1 – Setting up the Vuetify project

With our project initialized, we’ll create and configure a database to store our data.

Setting up the database

After registering for a free account on Supabase (https://supabase.com/), you’ll end up in the dashboard to create a new project. Let’s use fitness-tracker as the name and choose a strong database password. For the region, pick one that is geographically close to you for better latency. We’ll stick with the free plan!

On the next page (Figure 6.2), you will see the project API keys:

Figure 6.2 – Overview of the project API keys

Figure 6.2 – Overview of the project API keys

We’ll store them in our .env file in the root of our project:

VITE_SUPABASE_URL=YOUR_SUPABASE_URLVITE_SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY

Note that sharing keys like this via a client-side app always exposes them to the public. Luckily, Supabase has its own means of ensuring authentication while interacting with the database.

I’ve created a script that sets up the database with the table structure for our app. Via the dashboard and SQL editor, you...

Handling the user

The goal of the app is to allow for individual metrics to be tracked and viewed, so for that purpose, we need to make sure that we can identify our users. Supabase supports authentication out of the box, and we’re going to use a very basic method: a magic link.

A magic link allows you to sign up and sign in with just a valid email address. On logging in, the service sends an email containing a unique identifier, and when clicked, the user is verified to that email address. In our case, the backend handles verifying whether it’s a new user or an existing one, which is perfect for our use case.

Since we can identify users, we need to connect our app to retrieve information that Supabase provides. We can also introduce authentication to make sure that users have access to parts that they want to use or visit.

User store

We will want to have access and the ability to update the status of the user at all times, so we’ll set up a user store...

App state

To make it easier for us to control the state of the app, we’ll add a new store to track the current state of the user interface.

Vuetify has created a placeholder app store for us in the store/app.ts file, so we’ll add some features to handle page transitions (lines 28, 30-35), toggling a menu (lines 18, 20-26) and controlling a dialog (lines 37-55) for app-level notifications: https://github.com/PacktPublishing/Building-Real-world-Web-Applications-with-Vue.js-3/blob/main/06.fitness/.notes/6.6-app.ts.

Having access to these kinds of user interface utilities in a centralized place eliminates the need to repeat certain patterns in our app, such as showing or hiding a dialog. It means that those utilities are part of the app and are therefore available throughout the whole app.

Centralized dialog

Let’s update the FormLogin.vue file to make use of the store options on the app level. We can clean up the existing dialog options and replace them...

Exercise tracking

Let’s add a new route to have our users add a routine to the database. Let’s start by adding a new route entry on the routes:

      {        path: 'track',
        name: 'Track',
        component: () => import(/* webpackChunkName: "track" */ '@/views/Track.vue'),
        beforeEnter: loginGuard
      },

As you can see, this is a page that is only accessible by authenticated users. Our entry also means that we need to create a view, called Track.vue, so let’s continue:

<script lang="ts" setup>import TrackExercise from "@/components/TrackExercise.vue";
</script>
<template>
  <track-exercise />
</template>

We’...

Our hard work visualized

It is one thing to store the data. For the user, the data only has value if we can present it within a certain context. We’ve done a small exercise when displaying the compilation of a routine before saving. In this part, we’ll see a couple of different examples of displaying the data.

We’ll make sure to accommodate an empty state (so feel free to delete any items or try a new login), and after we’ve added some workouts, we’ll find ways to display the data.

Let’s start by replacing the home page. In this case, we already have a route and we have the Home.vue view, but we’ll remove the reference to the HelloWorld.vue component and create an empty History.vue <template> component instead. And then, in Home.vue, we’ll reference the History.vue file instead of HelloWorld.vue.

A view-based dashboard

We can start with a quick component to show the latest statistics of the user. When executing...

Summary

We’ve seen how we can use the concepts of stores, composables, and nested components to build a relatively complex user flow. For security, we depend on the authorization model by Supabase, which helps us achieve our results in an efficient way.

Taking a look at the Supabase structure and data is helpful in understanding the way certain endpoints store and offer their data. Up until this point, we’ve just been consuming data. Under the hood, every Supabase instance is a dedicated PostgreSQL database. If you want to know more about PostgreSQL, I highly recommend checking out Developing Modern Database Applications with PostgreSQL by Dr. Quan Ha Le and Marcelo Diaz, at https://www.packtpub.com/product/developing-modern-database-applications-with-postgresql/9781838648145.

With more complex tasks, it makes sense to take a step-by-step approach to building the feature, which is something I’ve also demonstrated. This sometimes means revisiting certain files...

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Building Real-World Web Applications with Vue.js 3
Published in: Jan 2024Publisher: PacktISBN-13: 9781837630394
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Author (1)

author image
Joran Quinten

Joran Quinten's passion involves getting people to love technology and getting technology to play nice. With over a decade of experience in developing and designing software, he has built up a broad background in development and architecture. He loves sharing knowledge and has been invited to speak at several tech events. Joran graduated from Fontys University of Applied Sciences, Eindhoven in 2010. Currently, he works for Jumbo Supermarkten, a national grocery chain where he is the technical lead of the design system team and acts as an ambassador for the tech department. He is passionate about mentoring and coaching junior developers. Joran lives close to Eindhoven with his wife, son and daughter.
Read more about Joran Quinten