Notelify - Take notes and unleash your ideas with friends in real time.

Notelify - Take notes and unleash your ideas with friends in real time.

INTRODUCTION

About Notelify

Notelify is a safe remote place to keep your notes, write down quick and immediate todos and share note taking with friends in real time.

The problem it seeks to solve.

I've always had this mindset that the greatest of ideas are usually the ones formed within a community or group of persons, two great minds is always better than one. In taking notes, I needed a simple piece of software that allows me to take notes, set quick todos and also share my notes or articles to as many collaborators as I want without the fear of having them see the notes and todos I'd want to be exclusive to just me and without any hidden or upfront charges. This idea was just another to put in the bin until an AWS Amplify x Hashnode hackathon notification came to me.

Sharing is caring too.

Share After hours of trying to draft out something good for your blog or school work, it's only normal to have mental blocks and get stuck with using the right words, why not invite your friends to help you out? you don't have to share your credentials! Just invite them for a collaboration and the rest will be fine. Notelify handles your note collaboration needs with a sleek and simple user interface.

FEATURES

Landing Page

A simple landing page a visitor or user first sees when opting to use the app. landing page.png

Authentication

I used Json web tokens for authentication.

Login screen

login.jpg

Sign up screen

signup.jpg

Dashboard.

The dashboard shows an overview of all notes, favourites, notes a user is collaborating on, notifications and archived notes. dashboard.jpg

Add Quicknote/Todo

Add a todo, task or quicknote easily. todo.jpg

Take notes.

The web app comes with a rich text editor where users can take and format their notes easily. editor.jpg

Collaboration

Other users can be invited to collaborate on a note. The invited user has the choice of accepting or rejecting an invite.

Invite potential collaborator

invite.jpg

Notifications: Accept or Reject Collaboration request.

notification.jpg

Bringing it all together

Coming Together Herein lies Notelify's development process, tech stack, issues encountered, lessons learned and future thoughts.

Tech Stack

  • AWS Amplify Studio : For building out UI components from a figma design for the React.js frontend.
  • AWS Amplify React.js UI library : For building out app pages and extra components.
  • AWS Amplify web hosting. : Hosted the frontend side of the app using AWS Amplify hosting service.
  • React.js : Built the app's frontend using React.js.
  • React router dom library. : Used in handling frontend page routing
  • Redux toolkit query. : Used in fetching and caching data without having to write much state management code.
  • Slate.js : An editable rich text package I used for text editing and formating implementation.
  • Toastify : Used for notifications when a user persons an action.
  • Socket.io : Used for real time collaboration.
  • NodeJS/Express : Used for app backend in building REST APIs
  • JSON Web Tokens(JWT) : Used for Authentication and Authorizing user requests.
  • MongoDB : Used for persisting user information and notes.
  • Railway Backend Hosting. : Used for hosting the backend.

Development process

With just 3 months of experience in backend development using Node.js, I had a hard time picking between Express and MongoDB or using AWS Amplify Data Modelling for the backend because I really wanted to hone my skills using Node.js. The solution or better pick was to use the AWS Amplify studio to build out my Frontend since I already had 2years of experience building with React.js. So it was a good opportunity to pick up a tool to make my build time with React.js lesser and then use Express and MongoDB to foster my learning process.

Project development timeline.

> September 03 - 05 : Project planning and choosing tech stack.
> September 07 - 19 : Build out and prepare the REST APIs
> September 21 - 28 : Build out the Frontend
> September 29 - 30 : Write the article

Backend Development

Initializing project and installing core dependencies.

git init
npm install --save-dev nodemon
npm install express mongoose jsonwebtoken dotenv socket.io cors

Project file structure

I opted to use package by feature on my backend code base by creating self-contained and independent packages in the form of USERS and NOTES. The result is a codebase that is easier to understand, seperated concerns and less error-prone.

/db
 -connectDB.js
/features
  /notes
    /controllers
      -index.js
    /models
      -index.js
    /routes
      -index.js
    /quicknotes
      -index.js
  /users
    /controllers
      -index.js
    /models
      -index.js
    /routes
      -index.js
/middleware
  -auth.js
/utils
  ---
  ---
.dockerignore
Dockerfile
app.js
package.json
package-lock.json

After installing dependencies and setting up project structure, I started off with creating a simple node.js server and connecting it to a mongoose data base and then set out to prepare API routes and controls for each feature.

Below are the HTTP verbs for users API routes.

- GET User
- GET Collaborators
- POST Sign Up
- POST Sign In
- POST Reset Password

HTTP verbs for notes API routes

- GET Notes
- GET Note
- GET Collab Notes
- POST Create Note
- PUT Update Note
- DELETE Delete Note
- POST Invite Collaborator
- POST Accept Invitation
- POST reject Invitation

Challenge

I knew little about relationship across tables or documents in a database, so it was quite difficult in grasping this concept while trying to construct a relationship between a user and many notes.

The solution I implemented

MongoDB has two ways of building a relationship between documents which are Embedded document model and Reference model. I went with Referenced model because it made more sense to me and it will be easier to scale with many users and users having alot of notes. Solution in Code

const { Schema, model } = require("mongoose")

const userSchema = new Schema({
    notes: {
      type: Schema.Types.ObjectId,
      ref: "Note",
    }
   // . . .other entries
  })

module.exports = model("User", userSchema)

Socket.io implementation for RealTime Collaboration.

I found this quite easy to implement, socket.io documentation was very easy to get information from. The below code snippet shows how i implemented realtime editing with socket.io on the backend.

const express = require("express")
const http = require("http")
const server = http.createServer(app)
const io = require("socket.io")(server, {
  cors: {
    origin: "*",
  },
})
io.on("connection", (socket) => {
  let state
  socket.on("text-changed", (data) => {
    const room = data.id
    state = data.newText
    socket.to(room).emit("text-changed", {
      newText: data.newText,
      ops: data.ops,
    })
  })
  socket.on("CONNECTED_TO_ROOM", (roomID) => {
    socket.join(roomID)
    socket.activeRoom = roomID
    io.in(roomID).emit("ROOM_CONNECTION", state)
  })
})

server.listen(PORT, startApp(connectDB))

Frontend Development

After having a friend to help me with the figma designs, I immediately started frontend development because i had just a week to implement the designs. All thanks to AWS Amplify studio for making the process alot faster.

Steps taken.

  • Revived my AWS console that has slept for up to a year.
  • Created a new app with AWS Amplify.
  • Synced the figma file to AWS Amplify Studio under UI Library jpg
  • Initialized a React.js project.
npx create-react-app Notelify
  • Installed AWS Amplify Command Line Interface
    github.io/amplify-cli/install-win -o install.cmd && install.cmd
    
  • Pulled the created ui-components to my react.js app. It worked like magic!
    amplify pull --appId dmj2py61vax3g --envName staging
    
  • Installed the dependency packages used by amplify.
    npm install
    
  • Installed Redux and Redux toolkit for caching and state management.
    npm install @reduxjs/toolkit redux
    
  • Went on to put the ui-components together to build the app.
  • Used the react router dom package to handle frontend routing.
  • The hardest part, implemented a rich text editor using slatejs. I did implement it in a day though.๐Ÿ˜Š
  • And Finally, hosted the app using AWS AMPLIFY WEB HOSTING

Challenge

I had a hard time using slatejs editor for realtime editing, I could barely find a use case in their documentaion, it was a real pain and considering the fact that I had just one day left before submission closes. I was quite frustrated and almost opted to use a bare text field to take notes, but thanks to some friends that helped me out in finding a solution to it.

Valuable Lessons Learned.

AWS Amplify was relatively easy to use. With my experience using it, my development time was far lesser than what it used to be. It's a wonderful tool now on my utility bucket and will be using it in my next project and more to come.

Test the app

master.d38cfclh6fsxhs.amplifyapp.com

Github Repo

github.com/osas2211/notelify

Testing Credentials

Test notelify with this public credentials.

{
  userName: awsamplify
  password: awsamplify
}

Conclusion

And finally, nothing good and worthy comes easy, my one month was well spent building Notelify. I'm very proud of how far I could push myself to continue with the project and hone my skills. I'd like to appreciate Aws Amplify and Hashnode for this opportunity to build out something this special.

ย