Losing users is a common problem for many apps. One way to keep users engaged is to reward them for their daily activities. A lot of apps do this by giving users a daily login bonus such as XP, coins, or a free award/badge. Some sites like coinmarketcap.com even give users a daily badge for visiting their site.
This is a great way to keep users engaged and coming back to your app every day. In this tutorial, we will be creating a daily badge rewards system for your users with JavaScript. The result will look like this:
Contents
- Prerequisites
- Getting Started
- Setting up the project
- Creating the frontend
- Creating the API
- Conclusion
Prerequisites
Before we get started, you will need to have some prior knowledge of the following.
- Next.js
- Prisma
Getting Started
Before, we start. We need to plan out the rewards system. I made a simple logic to determine the rewards. The logic is as follows:
- Every day, when the user logs in, they will see a button to claim their daily reward.
- The reward will be a badge of the day.
- The badge will be different every day.
- A user can only claim their reward once a day but they can have many badges of the same type.
- The user can claim their reward anytime during the day.
We will be using Next.js and Prisma to build this app. And for the badges, I made some png images using Stable Diffusion. Those images are saved inside a folder called badges
and contain the files.
?badges
┣ ?0.png <--- 0.png is the first badge (Monday)
┣ ?1.png
┣ ?2.png
┣ ?3.png
┣ ?4.png
┣ ?5.png
┗ ?6.png <--- 6.png is the last badge (Sunday)
Setting up the project
First, we need to start a new Next.js project with Prisma. Previously, I wrote a tutorial on how to set up a Next.js project with Prisma. You can check it out here. We will clone the git repo and install the dependencies.
You can use npm
or yarn
instead of pnpm
if you want.
Now we need to make our database schema. Open the schema.prisma
located in the prisma
folder and add the following code.
We have two models in our schema. The CollectedBadges
model will store the badges that the user has collected. The Users
model will store the user’s name and the last badge that they collected. The lastBadgeId
field will be used to determine the next badge that the user will collect.
For example, if the user collected the badge for Monday, the lastBadgeId
will be the ID of the last collected badge ID received from the CollectedBadges
model.
Oh, and we also need to add the DATABASE_URL
environment variable to our .env
file. Use the below format in your .env
file.
DATABASE_URL='mysql://username:password@host:port/database'
Now we can migrate our database schema.
This will create all the required tables and columns in our database.
Creating the frontend
Start the development server.
Now, we need to create the pages. We will create two pages. Delete all the folders and files inside the pages
folder except the _app.tsx
,_document.tsx
, and index.tsx
files.
Copy the badges folder into the public
folder. This will make the badges available to the public.
Edit the index.tsx
file and add the following code.
Here we are fetching the badges from the API and displaying them. We are also adding a button to collect the badge which will call the API to collect the badge.
You will notice some error messages because we haven’t created the API yet ?. Let’s do that now.
Creating the API
The first thing we need to do is create a new folder in the pages
folder called api
. This is where we will store all of our API routes. The first API is collect.ts
which will be used to collect the badge.
We first import the types and the database library.
Then we create the handler function which will be called when the API is called. We make it async because we use the await
keyword.
We define a constant named USER_ID
which will be used to identify the user. We use a static value for now because we haven’t implemented authentication yet. Before we continue, you need to manually create a user in the database. You can do this by running the following command in the terminal.
This will open the Prisma Studio. You can then create a user by clicking on the add button.
After you have created the user, you can get the ID of the user by clicking on the user and copying the ID. In my case, the ID is 1
.
Then we define some functions.
The dayNumber
contains the number of the day starting from Monday. We do this because the database stores the days starting from Monday. If the day is Sunday, we set it to 7.
We then get the last collected badge ID of that user.
Then the below code is self-explanatory.
After we have defined the handler function, we export it.
That’s it for the collect.ts
API. Now save the file and try clicking on the collect badge button. You should see a success message. Now if you explore the database, you will see that a new badge has been added to the collectedBadges
table.
Nice! Now let’s create the next API which will be used to get the badges.
Create a new file called getCollectedBadges.ts
in the pages/api
folder. Then add the following code.
The code is self-explanatory. We get the badges from the database and then return them. Now save the file and try refreshing the page. You should see the badges with the count.
That’s it for the API.
Conclusion
So, that’s a wrap for this tutorial. I hope you enjoyed it. If you have any questions, feel free to ask them in the comments. The code for this tutorial is available on GitHub.
Connect with me on Twitter and GitHub
Cheers!