KanbanProject Management Tool

What is it?

This project is my web app implementation of a Kanban board. It allows the user to organize their tasks for different projects in 2 dimensions: vertically by priority and horizontally by status.

Features

  • CRUD operations for all data (boards, tasks, etc.)
  • Error Handling on form submission with retry
  • Optimistic Updates w/ rollback on error
  • Loading states and skeletons
  • Account creation and access with OAuth
  • Drag & Drop of tasks within and between columns
  • Responsive design for mobile, tablet, and desktop
  • Light/Dark mode
  • Collapsible sidebar

Tech Used

Next.js logo

Framework

Typescript logo

Language

Tanstack Query logo

Data Management

PostgreSQL logo

Database

Prisma logo

ORM

NextAuth.js logo

Auth

Tailwind logo

Styling

dndkit logo

Drag & Drop

Data Modeling

The data in this project was largely relational one-to-many relationships: one user has many boards, one board has many columns, etc.

For this reason, I chose to use a PostgreSQL database as it seemed to be a solid, well-known option as a relational database.

Relation diagram for the Kanban app

Data Retrieval

Data retrieval diagram for Kanban app

I used data utility functions that wrapped axios requests to an API layer. In the API route handlers, I used Prisma to retrieve the data from the db. The abstraction of the data util functions creates a clear separation between my app and the data that it uses, mitigating the need for changes in my app if the API or database changes.

Code Highlight

Dynamic Inputs

The dynamic nature of the input lists used for columns and subtasks provided an extra challenge as multiple CRUD operations had to be performed in a single request: add, edit, and delete.

To accomplish this, I used the data shape shown. An object with arrays for creation, updating, and deletion. Depending on the action taken by the user, multiple arrays could be updated, each with their own logic.

For instance, if the user edits a column, the “create” array is put through a map whose behavior is governed by the length of the “update” array because the “create” array always appears at the bottom of the dynamic list. The “update” array is mapped in the typical way for a change handler. Finally, the “delete” array is simply spread out with no mapping since it is never rendered (but it is sent to database for the deletion of the appropriate items!)

Auth

I chose NextAuth for it's easy integration into Next.js projects and Github as the OAuth provider. When a new user signs in, a new UUID is created in User table of the database and is associated with the user's email. On subsequent logins, the email is found in the database and the user is redirected to their boards. The UUID for the user can seen in the URL.

Drag & Drop

After some research, I chose dndkit to handle dragging & dropping of tasks. This was mostly due preferring the API over those of other React drag and drop options and the customization available with dndkit. To provide a better user experience and maintain data integrity, task grouping and ordering data is updated in the local cache (using TanStack Query) during dragging and is only synced to the database when the user finishes dragging. In the event of an error, tasks are rolled back to their previous positions. The user is also prevented from dragging again until task data is retrieved from the server. This isn't ideal, but an ideal solution seemed like it would've added a lot of complexity and dev time so I decided to go with the simpler solution.