Enhancing user experience with real-time health data insights in Nuxt.js
Moronfolu Olufunke
Posted on March 17, 2023
Real-time data processing involves almost instantaneous feedback after program execution. This type of processing is critically important in the health field to track and monitor items such as user dosage or patient test results to decide on a patient's health status.
In this article, we will demonstrate the use of Appwrite to build application in Nuxt.js that allows tracking and enhancing user experience by leveraging on Appwrite's real-time feature. Appwrite is a self-hosted backend-as-a-service platform that provides developers with all the core APIs required to build any application
GitHub
Check out the complete source code here.
Prerequisites
Understanding this article requires the following:
- Installation of Node.js
- Basic knowledge of JavaScript and Vue.js
- Docker installation
- An Appwrite instance; check out this article on how to set up an instance locally or via one-click install on DigitalOcean or Gitpod
- Installation of the Appwrite CLI
Creating a Nuxt project
Use npx create-nuxt-app <project-name>
to create a new Nuxt.js project.
Scaffolding the Nuxt.js project provides a list of options, from which we will pick the one that best suits our preferences.
We can start our Nuxt3 application by running the following command:
cd <project name>
npm run dev
Nuxt.js will, in turn, start a hot-reloading development environment that is accessible by default at http://localhost:3000
.
Creating an Appwrite project
To create a new project, we will start the Appwrite instance on our machine and navigate to the specified hostname and port http://localhost:80
. Next, we must log into our account or create an account if we don't have one.
Learn more about setting up Appwrite here. On the console, click on the Create Project button.
The project dashboard becomes visible on the console after the project creation. We can access the inner page from the Settings tab at the bottom of the page.
The inner page allows us to copy the Project ID and API Endpoint for our Nuxt application.
Adding Appwrite Web SDK to Nuxt.js
We will then proceed to create an init.js
file in our Nuxt.js application's root directory to initialize the Appwrite Web SDK by adding the code block below:
import { Client, Account, functions } from "appwrite";
export const client = new Client();
export const account = new Account(client);
client
.setEndpoint('http://localhost/v1') // API Endpoint
.setProject('***') // project ID
;
export const insightFunction = () => {
const functions = new Functions(client)
return functions.createExecution('***') // Function ID
}
Creating an Appwrite function
Among Appwrite's supported runtimes for creating a serverless function is Node.js. Appwrite's serverless function gives room to build on and customize Appwrite server functionality by adding and executing our custom code.
Integrating Appwrite function in Nuxt.js
We will start by logging onto Appwrite's server using the Appwrite command-line interface (CLI), like so:
appwrite login
Running the command above requires us to use our Appwrite credentials in the terminal.
After logging into the application, we will initialize and link the Nuxt.js application with the previously created Appwrite project. To do this, we will run the command below:
appwrite init project
Running the command above will display a list of options from which we will pick those appropriate for our project.
Next, let’s create a function in our Nuxt.js application. We will do this by running the command below:
appwrite init function
At the successful execution of the above command, we will see a new folder named functions/<function-name>
in our Nuxt.js application.
Deploying the Appwrite function
To deploy the Appwrite function, we will run the command below:
appwrite deploy function
Executing the above command will require us to pick the appropriate function we want to deploy. Upong successful deployment, we will get a message like the one below in our terminal.
✓ Success Deployed <function-name> ( functionID)
In our Appwrite function console, we will also have a view that looks like the below:
This signifies the successful deployment of our Appwrite function.
We will also update the function's permissions to allow access within the Nuxt.js application. To do this, navigate to the Settings tab and add a role of any
to the Executive Access field:
Creating the signup page
We will create a signup page where people who will later be assigned roles to perform certain operations within the database can generically create an account. To do this, we will create a components/Sign-up.vue
and add the code below:
<template>
<div class="ba b--light-blue bg-light-blue bw3 vh-100 pv5 ph2 athelas">
<form @submit.prevent="signUp" class="white bg-navy br3 mw6 w-40-m w-70 w-20-l center pa3 shadow-5">
<h2 class="ttc tc">Sign up</h2>
<label for="name" class="db mb1 white">Name</label>
<input name="name" id="name" type="text" class="db mb3 w-100 br3 pa2 ba bw2" placeholder="John Doe" v-model="name">
<label for="email" class="db mb1 white">Email</label>
<input name="email" id="email" type="email" class="db mb3 w-100 br3 pa2 ba bw2" placeholder="example@email.com" v-model="email">
<label for="password" class="db mb1 white">Password</label>
<input name="password" id="password" type="password" class="db mb3 w-100 br3 pa2 ba bw2" placeholder="••••••••" v-model="password">
<label for="confirm-password" class="db mb1 white">Confirm Password</label>
<input name="confirm-password" id="confirm-password" type="password" class="db mb3 w-100 br3 pa2 ba bw2" v-model="confirmPassword" placeholder="••••••••">
<button type="submit" class="center db ph4 pv2 bg-navy ba br3 white pointer">Sign up</button>
<p>Already have an account? <a href="/signin" class="white b">Sign in</a> </p>
</form>
</div>
</template>
Implementing the code block above, we achieved the following:
- Created a functional form to handle input from potential users of our dashboard
- Added the
data
in the Vue script to manage the username, email, and password of the people who will fill out the form
Adding the signup functionality
Our interface will need to be connected to Appwrite to authenticate users. To do this, we will add the following code in the <script>
tag of our components/Sign-up.vue
file.
<script lang="ts">
import Vue from 'vue'
import {account} from '~/init'
export default Vue.extend({
data: () => ({
name: "",
email: "",
password: "",
confirmPassword: ""
}),
methods: {
signUp: async function(){
if (this.password.length >= 8){
if(this.password === this.confirmPassword) {
try{
await account.create('unique()', this.email, this.password, this.name)
alert("account created successfully")
window.location.href = '/signin'
} catch (e) {
console.log(e)
}
} else {
alert("password do not match")
}
} else {
alert("password length should be up to 8 characters")
}
},
}
})
</script>
The code block above achieves the following:
- Imports the Appwrite SDK initialized in the
init.js
file. - Creates the
signUp
function in themethods
property, which performs the following functions:- Verifies that the password length is equal to or greater than eight characters.
- Confirms that the characters in
password
andconfirmPassword
are the same. - Accesses Appwrite's services using the
account.create
to create a new account using the user's email, password, and name.- To use Appwrite's create account service, it's mandatory to add the
userId
; in this case, we useduniqueId
to generate one automatically. - Adding
email
andpassword
is also mandatory. - The
name
option is optional; we can create an account without one.
- To use Appwrite's create account service, it's mandatory to add the
-
window
.location.
href
allowed us to navigate to the insight interface after successful account creation.
Next, let's import the components/Sign-up.vue
into the pages/index.vue
, like so:
<template>
<div>
<Signup/>
</div>
</template>
At this point, our signup page should look like the below:
Creating the sign in interface
We also need to create a sign in page that allows registered users to log in to the dashboard. To do this, we will create a pages/Signin.vue
and add the code below:
<template>
<div class="ba b--light-blue bg-light-blue bw3 vh-100 pv5 ph2 athelas">
<form @submit.prevent="signIn" class="bg-navy br3 mw6 w-40-m w-70 w-20-l center pa3 shadow-5 white">
<h2 class="ttc tc">Sign In</h2>
<label for="email" class="db mb1 white">Email</label>
<input name="email" id="email" v-model="email" type="email" class="db mb3 w-100 br3 pa2 ba bw2" placeholder="example@email.com">
<label for="password" class="db mb1 white">Password</label>
<input name="password" id="password" v-model="password" type="password" class="db mb3 w-100 br3 pa2 ba bw2" placeholder="••••••••">
<button type="submit" class="center db ph4 pv2 bg-navy ba br3 white pointer">Sign in</button>
</form>
</div>
</template>
The code block above achieves the following:
- Creates a functional form to handle input from registered users
- Adds the
data
in the Vue script to manage the email and password
Adding the signin functionality
Our interface must be connected to Appwrite to authenticate users for signing in. To do this, we will add the code below in the Signin.vue
.
<script lang="ts">
import Vue from 'vue'
import {account} from '~/init'
export default Vue.extend({
data: () => ({
email: "",
password: "",
}),
methods: {
signIn: async function () {
try{
let accountDetails = await account.createEmailSession(this.email, this.password)
alert("user signed in")
this.$router.push({ path: `/insight/${accountDetails.userId}`})
} catch (e){
console.log(e)
}
}
}
})
</script>
Above, we imported the Appwrite SDK initialized in the init.js
file. We also created a function called signIn
that does the following:
- Accesses Appwrite's services using the
account.createEmailSession
to create a new account session using the user's email and password -
this.$router.push
allows us to navigate to the insight interface after successful user login
At this point, our interface will look like this:
Setting up Appwrite's database
One of the services offered by Appwrite is the Database Service, which allows us to store data and fetch it as needed.
Creating a database
To create a database in Appwrite, click on the Database option in the menu tab, where we can add a database to the system.
Creating a collection
Appwrite's database services also provide collection services. These collections act as containers for documents. To create a collection, select the desired database from which we can add a new collection.
Creating an attribute
Our document will have some particular attributes. To create them, we will navigate to the Attributes section. In our case, we will choose the Boolean Attribute. We can then create an Attribute ID with the name "doses".
Now, will set the permission roles for the document. Click on the Settings tab, and in the Role input field, pick the role that best describes to whom we are giving access.
In our case, the role is any, and we will allow all four actions: create, read, update, and delete.
Creating the Insight page
We will be creating a page where we track users' dosages. Every day a user is allowed to take just three doses, after which they are prompted to log in the next day to get access to more doses.
We will start by creating an interface that allows users to log their dosage. To do this, we will create a pages/_insight/insight.vue
and add the code below:
<template>
<div class="bg-light-blue vh-100 pa3 tc">
<h2 class="ttc">Real Time Health Data analytics with Appwrite</h2>
<div class="br3 bg-navy ba near-white b--black-10 shadow-3 w-100 w-60-m w-30-l mw6 center mt5 ph4 pv4 h5">
<p class="f3">Click on this button to get the dosage</p>
<button class="link br3 pv2 ph2 mt4 dib black fw6 bg-white ba b--navy pointer inline-flex items-center hover-bg-lightest-blue" @click="getDosage">
<span class="f4 ml2 pr2">Get dosage</span>
</button>
</div>
</div>
</template>
The code above achieves the following:
- Creates an interface where users are redirected after sign up or sign in
- The insight interface allows users to click on a button
getDosage
to track their dosage journey for each day
Adding the getDosage() functionality
Now we will connect the interface to a working functionality that allows users to log and track their dosage.
<script>
import {client, insightFunction} from '~/init'
import { Databases } from "appwrite";
const databases = new Databases(client);
import moment from "moment";
export default {
data() {
return {
permisssionsArray: [],
}
},
mounted() {
insightFunction().then((res)=> res).catch((error)=> {
console.log(error)
})
this.checkDosage();
if(this.$route.params.insight){
try {
client.subscribe("documents", (response) => {
this.checkDosage();
});
} catch (error) {
console.log(error, "error");
}
}
},
methods: {
moment,
async getDosage() {
await databases.createDocument(
"63ef7e057f16c9d0b811",
"63ef7e389fdfbe02d8e9",
"unique()",
{
doses: true,
}
);
},
async checkDosage() {
const dosageDetails = await databases.listDocuments(
"63ef7e057f16c9d0b811",
"63ef7e389fdfbe02d8e9"
);
dosageDetails.documents.filter(obj => {
if( moment(obj.$createdAt).format("YYYY-MM-DD") === moment().format("YYYY-MM-DD")) {
obj.$permissions.find(element => {
if(element.includes(this.$route.params.insight)) {
this.permisssionsArray.push(element)
if (this.permisssionsArray.length >= 3){
this.$swal({icon: 'success', title: 'Wait one day before taking another dose. Take a walk instead', timer: 10000, showConfirmButton: false,});
}
return;
} else {
return;
}
})
}
})
}
}
}
</script>
The code above achieves the following:
- Imports the dependencies from the
init.js
file as well as from Appwrite. - Installed the moment.js package, which we used for checking and comparing the days for the dosages.
- The
getDosage
method accesses thedatabases
method from Appwrite to create a new document in the database. This method takes thedatabase ID
,collection ID
, Appwrite'sID.unique()
method, and the attribute value(s) as parameters. In this case, our attribute value isdoses
, which we created on the Appwrite admin dashboard. - We call the
listMessages()
function, which lists all the messages that were sent to the Appwrite's database. - Checks whether the user has taken up to 3 doses and shows a notification telling the user to come back the next day.
At this point, our application should look like the below:
Conclusion
This article discusses enhancing user experience by providing data insights using Appwrite's real-time features.
Resources
Posted on March 17, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.