Skip to content

Josuto/weather-app

Repository files navigation

This is a simple single-page weather app made in Next.js and React.

CI Status Test results Coverage

Table of Contents

  1. How it works
  2. Followed practices
  3. App Architecture
  4. Commands
  5. Used technologies

How it works

The intent of this app is purely academic; I created it to further practice my knowledge in web front-end app development in React and Next.js. This weather app specifies a dropdown list that serves as a municipality search bar so that any user can pick one at a time. When she does it, a card showing several weather data (max, min, and current temperature, rain probability, etc.) is displayed.

Cards include a save and a close button. When clicking on the save button, some municipality identification data is stored at the local storage of the user's browser, thus enabling the weather app to re-fetch the weather data of her favourite municipalities whenever she comes back to the site where the app is hosted (unless she manually deletes the browser local storage contents). Once saved, the user is also able to discard the card from her favourite municipalities, thus deleting its related data from the local storage.

The close button, on another hand, not only removes the card from the view, but also deletes its related data from the local storage.

Last but not least, the weather app only works for Spanish municipalities, but I am pretty sure that you are smart enough to update or even scale it to make it work with other municipalities around the world ;-)

Followed practices

I followed Test Driven-Development (TDD) to build this app. This means that before writing any new feature, I first focused on building a test that I expected the code to pass following the red-green-refactor loop. That way, paraphrasing Dave Farley, I was able to work in small steps and getting really useful feedback on my endeavour.

On the topic of validation, it is also worth mentioning that I followed Kent C.Dodds' Testing Trophy methodology to write the right (mostly integration) tests to gain the required confidence on the validity of my code.

Another important point to mention is that single-page is not synonym of putting all the code in one single file. Despite React is some fantastic library to build front-end applications, we (developers) should follow standard patterns and techniques to modularise our web apps, as mentioned by Juntao QIU in this inspiring article. So I did.

Finally, I also followed the trunk-base development methodology. Not to say that I needed any other Git workflow for this project since I am the one and only developer of this app, but I wanted to highlight the main benefit of this methodology: avoid the merge hell. Besides, I truly believe that you do not need other branches when it comes to build an app meant to provide users with new features (use feature toggles/flags if you are to incorporate experimental ones).

App Architecture

The app’s core flow is:

  1. src/app/page.tsx is a server component (RSC). It fetches municipalities via a server-side function (fetchMunicipalities) and passes them as props to AppRoot.
  2. AppRoot renders MunicipalitySearchBar with all municipalities and keeps selected municipalities in a client state (municipalities).
  3. Selecting a municipality in the dropdown updates state in AppRoot, which re-renders and adds a new MunicipalityCard.
  4. Each MunicipalityCard loads weather data using useSWR and a route handler at src/app/api/municipalities/[municipality]/weather-data/route.ts (currently calling AEMET).
  5. The user can mark a municipality as favourite, which stores it in browser local storage, or unmark it to remove it from favourites.
  6. Closing a card removes it from the grid and from local storage.

All user-initiated operations are marked by user actions (select municipality, mark/unmark favourite, close card). Component re-renders are intentionally not illustrated for clarity; they are implied by state updates.

Weather App Architecture

Additionally, data fetching and transformation to domain objects are decoupled in src/infrastructure. This acts as an anti-corruption layer and makes it easy to change the upstream municipality provider without affecting component logic.

Commands

  • pnpm dev — Run the app locally in development mode (hot reload). Open http://localhost:3000.
  • pnpm start — Start the production server after building, typically used after pnpm build in deployment.
  • pnpm test — Run tests (Jest + React Testing Library) to validate behavior and regression safety.

Used technologies

Here is a list of the most outstanding technologies that I used to implement this app:

Releases

No releases published

Packages

 
 
 

Contributors