Back to projects list

Project: Task machine

Open
github_icon GitHub

Languages

typescript

Typescript

Libraries / Frameworks / Technologies

next

Next

redux

Redux

pwa

PWA

tailwind

Tailwind

This is my biggest project until now. These are its key features:


The initial state

I decided to init the Redux state in the client side, through a <Init /> component with 2 effects:

  1. Intialize the Redux state.
  2. Once per day, show a modal telling the user that they have pending habits. (the habit reminder)

Middlewares

Storage

Automatically updated the localStorage data on every change.

Theme

Automatically updating the html dark class (tailwind) on every change.


There a 2 types of tasks: tasks and habits.

Tasks

Simple tasks. They have a done key with a boolean value. But also have a difficulty level and a due date. Tasks can (or not) be put into groups.

Groups

The groups are a collection of tasks. They have a color, a name and a list of tasks.

Habits

They are pretty similar to tasks, but with a small difference: they have a days key wich refers to the weekdays that the habit must be done. If the actual day is not included in the weekdays of the habit, it will be shown as disabled in the screen.

The problem

There was a problem with habits: if I wanted the app to work offline, I needed to be able to restart the habits in the client-side. But browser JS cannot execute background processes, like it would in a server.

The solution that I found is to use useLayoutEffect to check the habit before rendering it. This works with the redux reducer checkHabit, which sets the done key to false. If the habit lastChecked date is different from the current day, checkHabit reducer will be called.

Even though it works fine, this is not great for performance. Since this requires to make a date check every single time that a habit is rendered.