Skip to content

Repository with my solution to the Frontend Mentor "Todo app" challange.

Notifications You must be signed in to change notification settings

carlaalmeida/todo-app

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Frontend Mentor - Todo app solution

This is a solution to the Todo app challenge on Frontend Mentor. Frontend Mentor challenges help you improve your coding skills by building realistic projects.

Table of contents

Note: Delete this note and update the table of contents based on what sections you keep.

Overview

The challenge

Users should be able to:

  • View the optimal layout for the app depending on their device's screen size
  • See hover states for all interactive elements on the page
  • Add new todos to the list
  • Mark todos as complete
  • Delete todos from the list
  • Filter by all/active/complete todos
  • Clear all completed todos
  • Toggle light and dark mode
  • Bonus: Drag and drop to reorder items on the list

Screenshot

Screenshot of the solution

Links

My process

Built with

  • Semantic HTML5 markup
  • Sass
  • Flexbox
  • Mobile-first workflow
  • React - JS library
  • react-beautiful-dnd - a library that allows drag and drop for lists in React

What I learned

This project helped me to get more familiar with React, especially the useState and useEffect hooks.

This was also my first time using Sass in a React project, which proved to be very straightforward.

For me, the most challenging part of the project was implementing the Drag and Drop feature. Even though it was an optional feature of this challenge, I wanted to give a go and add it to the final app. After some research, I decided to use the existing react-beautiful-dnd library. It provided a simple and effective way to implement this feature.

Another feature I was dreading was the light and dark mode toggle, simply because I had not done it. I broke down this feature into small steps:

  1. First, I wrote all the styles in the style.scss file. Using the light theme as the default, I simply created a .dark class that overwrites the properties that needed to change when switching themes:
.dark {
  background-colour: $clr-dark-neutral-700;
  background-image: url("../public/images/bg-mobile-dark.jpg");
  colour: $clr-dark-neutral-200;

  /* .... */
}
  1. Then, I implemented the ThemeSwitcher component, which is rendered by the main App component and is responsible to display the appropriate symbol to change the colour palette.

  2. The App component is responsible to handle the changing of the theme and applies the class of the selected theme in the handleChangeMode

  3. After having the basic functionality working, I wanted to somehow persist the user's choice so that when they refresh the page (or return to it) it would still display their desired mode. To achieve this, I made use of JavaScript's localStorage property. With this property, we can set a new item with the selected mode, and then retrieve it when the user refreshes the page or opens a new instance of the app.

const [mode, setMode] = useState(null);

// run on load to get the stored theme
useEffect(() => {
  const storedMode = localStorage.getItem("mode");
  if (storedMode) {
    setMode(storedMode);
    if (storedMode === "dark") {
      document.body.classList.add("dark");
    }
  } else {
    setMode("light");
  }
}, []);

// setting the colour mode
function handleChangeMode() {
  if (mode === "dark") {
    setMode("light");
    localStorage.setItem("mode", "light");
  } else {
    setMode("dark");
    localStorage.setItem("mode", "dark");
  }
  document.body.classList.toggle("dark");
}
  1. Finally, I wanted to add some more detail to this feature. Previously, I stated that by design the Light Mode was the default one, but these days so many people have their devices set with a dark mode (myself included!), so I thought it would have been a nice touch to have this application detecting the user preference even if they are using the app for the first time. This also required some research, but quickly I found out about the prefers-colour-scheme CSS media query, which allows us to define CSS rules depending on the colour-scheme the user has set on their device. However, I wanted a Javascript approach and not a CSS one, because even if the user has prefers-colour-scheme set to dark on their device they could have chosen to use the app in light mode, or vice-versa. To check this, I used the window.matchMedia Javascript interface, and use it to check if the user has the prefers-colour-scheme media query set to dark, and change the theme accordingly.
// run on load to get the stored theme
useEffect(() => {
  const storedMode = localStorage.getItem("mode");
  if (storedMode) {
    setMode(storedMode);
    if (storedMode === "dark") {
      document.body.classList.add("dark");
    }
  } else if (storedMode === "light") {
    setMode("light");
  } else if (
    window.matchMedia &&
    window.matchMedia("(prefers-colour-scheme: dark)").matches
  ) {
    setMode("dark");
  } else {
    setMode("light");
  }
}, []);

Continued development

I look forward to keeping using React on my future projects, exploring more of its features and expanding my knowledge of hooks.

For this specific project, I intend to build a back-end using Node and Express and make it a full-stack web application.

Useful resources

Author

About

Repository with my solution to the Frontend Mentor "Todo app" challange.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published