abelcastro.dev

Building Fasting Timer 18:6: A Learning Journey with React, Next.js, and More

2024-07-26

TypeScriptTestingTailwindNext.js

Fasting Timer 18:6

In my journey of learning more about React and Next.js, I created a new project: Fasting Timer 18:6. In this blog post, I'll take you through the details of the project, the key learnings, and some interesting technical aspects that might be helpful for fellow developers.

You can check out the project repository here and try the live app here.

Project Overview

Fasting Timer 18:6 is a simple yet effective application designed to help users manage their intermittent fasting schedules. The 18:6 fasting method involves fasting for 18 hours and eating during a 6-hour window. This app helps users keep track of their fasting and eating times with ease.

Key Learnings

Working on this project provided me with several valuable learning opportunities:

  1. Testing React Apps with Jest
    • Writing tests for React applications was one of the primary goals of this project. Using Jest, I was able to create a comprehensive test suite to ensure the app functions correctly. Testing not only helps in catching bugs early but also makes the codebase more maintainable.
    • Here's a snippet of a simple test case:
	import { render, screen, fireEvent, act } from "@testing-library/react";
	import Home from "../app/page";
	import storageService from "../app/storage/storage-service";
	
	it("should start the timer and switch to fasting/eating mode after clicking the button", async () => {
    	const { container } = render(<Home />);
    	
    	expect(container).toMatchSnapshot();
    	
    	// Start fasting
    	const button = screen.getByRole("button", { name: /Start fasting/i });
    	await act(async () => {
    	  fireEvent.click(button);
    	});
    	
    	expect(container).toMatchSnapshot();
    	
    	const startFastingTime = storageService.getStartFastingTime();
    	expect(startFastingTime).toBeInstanceOf(Promise<Date>);
    	// ...
	});
  1. Creating a Coverage Badge with Codecov.io
    • Integrating Codecov.io allowed me to monitor test coverage. This step was crucial in ensuring that a significant portion of the code is tested, providing a clear picture of areas that might need more attention.
    • The coverage badge is prominently displayed in the repository, serving as a quick reference for the project's test coverage status.

The StorageService Concept

One of the interesting aspects of the project is the StorageService. This service is designed to manage the storage and handling of fasting and non-fasting times.

Key Points:

  • BrowserStorage as Default Provider: Currently, the default storage provider is BrowserStorage, which stores data in the user's local browser storage.
  • IStorageProvider Interface: To make the storage service flexible, an IStorageProvider interface is defined. This interface outlines the necessary methods that any storage provider must implement.
  • Ease of Changing Persistence Layer: With this setup, changing the persistence layer (e.g., from local storage to a database) becomes straightforward. One only needs to implement the IStorageProvider interface and update the storage service configuration.

Example Implementation:

const storageService = new StorageService(new BrowserStorageProvider());

export default storageService;

With this design, changing the persistence layer is as simple as touching two files—implementing the new storage provider and updating the configuration.

Conclusion

Working on the Fasting Timer 18:6 project has been an enriching experience. From learning to write tests with Jest to creating a flexible storage solution, each step has contributed to my growth as a developer. I hope this blog post provides valuable insights and encourages you to explore and implement these concepts in your projects.

Feel free to check out the repository, try the app, and provide any feedback or contributions. Happy coding!

Try the live app here.