Skip to content

JhonatanLop/weather-forecast

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

52 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Weather Forecast App 🌤️

Este projeto é uma aplicação web de previsão meteorológica que permite aos usuários consultar as previsões do tempo para qualquer cidade utilizando um mapa de apoio. A aplicação foi desenvolvida utilizando TypeScript e a biblioteca OpenLayers para o mapa.

Funcionalidades

  • Pesquisa de Cidade: Os usuários podem pesquisar por uma cidade e obter informações detalhadas sobre o clima atual.
  • Mapa Interativo: O mapa exibe a localização da cidade pesquisada e atualiza dinamicamente conforme novas pesquisas são realizadas.
  • Informações do Clima: Mostra a temperatura atual, temperatura máxima e mínima, tipo do clima e ícones correspondentes.
  • Cidades Salvas: Os usuários podem acessar rapidamente as cidades pesquisadas anteriormente através de um menu de seleção.

Tecnologias Utilizadas

As APIs utilizadas para esse projeto são gratúitas e infelizmente não possuem dados relacionados às fases da lua ou uma previsão de até 3 dias do clima da região selecionada como foi solicitado

Estrutura do projeto

cypress
├── e2e/
│   ├── TestandoApp.cy.js
│
weather-forecast/
├── public/
│   ├── index.html
│
├── src/
│   ├── components/
│   │   ├── CitySearch.tsx
│   │   ├── Popup.tsx
│   │   ├── Map.tsx
│   │   ├── WeatherInfo.tsx
│   │   ├── SavedCities.tsx
│   │
│   ├── service/
│   │   ├── api.ts
│   │
│   ├── styles/
│   │   ├── app.css
│   │   ├── global.css
│   │   ├── index.css
│   │
│   ├── App.tsx
│   ├── main.tsx
│
├── .gitignore
├── package.json
├── tsconfig.json
├── README.md

Instalação

### Pré-requisitos
  • Node.js
  • npm ou yarn

Passos para Instalação

  1. Clone o repositório:
git clone https://github.com/JhontanLop/weather-forecast.git
cd weather-forecast/weather-forecast/
  1. Instale as dependências:
npm install
yarn
  1. Configure suas chaves de API:

Para conseguir uma api key acesse o site da openWeather e crie uma conta se não tiver. Depois vá para a parte de API keys onde estarão listadas todas as suas chaves.

openWeatherpage

No arquivo api.ts coloque a sua chave de acesso

const WEATHER_API_KEY = "YOUR_API_KEY";
  1. Inicie a aplicação:
npm run dev
yarn dev

A aplicação estará disponível em http://localhost:3000.

Como usar

Tela inicial

tela_inicial

O sistema faz o uso da API externa a partir do campo de pesquisa com input do tipo string e um botão ao lado para fazer a chamada da função.
Pesquisando pelo nome de uma cidade o primeiro endpoint será usado. Este recebe como parâmetro o nome de uma cidade e retorna algumas informações como latitude e longitude
Esses dados são usados em outro endpoint que retorna os dados do clima naquela regial. Se a consulta for bem sucedida, o mapa será movido em direção à cidade e as informaçãos sserão reenderizadas na tela e a cidade pesquisada vai para a lista no canto superior da página.

pesquisa

Caso pesquise por uma cidade e a mesma não é encontrada haverá um popup de aviso.

pesquisa_sem_retorno

Testes automatizados

Para executar os testes automatizados

  1. Instalar dependências
npm i cypress --save-dev
  1. Executar testes
npx cypress run

Esse comando irá rodar os testes e exibir um relatório pelo terminal.

Usando interface do Cypress
  1. Abrir o cypress
npx cypress open

Este comando irá abrir o cypress, onde executara os testes em tempo real com uma interface para visualização do processo

  1. Fazer login

cypress_home

  1. Escolha o tipo de teste

tipo_teste

Para esse projeto usaremos a opção E2E

  1. Escolha do ambiente a ser executado

escolha_ambiente

No meu caso eu acabei usando o firefox pois é o navegador que eu possuo

  1. Escolha o teste

escolha_test

Ao escolher o teste, o cypress comecará os testes

test

Documentação técnica

OpenWeather Geocoding API: Documentação
OpenWeather Current weather data: Documentação)
OpenLayer documentation)

Fluxo dos dados da aplicação

  1. Obtendo os dados.

Ao pesquisar o nome de uma cidade, usa-se o end-point:

export const getCityCoordinates = async (city: string) => {
const response = await axios.get(`https://api.openweathermap.org/geo/1.0/direct?q=${city}&limit=1&appid=${WEATHER_API_KEY}`);
return response.data[0];
};

Esse endpoint retorna a latitude e longitude da cidade junto com outras informações como estado e país. A latitude e longitude será usado na reenderização do mapa e em outro endpoint, este que retorna os dados do clima

export const getWeather = async (lat: number, lon: number) => {
  const response = await axios.get(`https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${WEATHER_API_KEY}&lang=pt_br`);
  return response.data;
};

função que atualiza a posição do mapa

setMapPosition({ lat: cityData.lat, lon: cityData.lon, zoom: 11 });
  1. Convertendo os dados

estes dados vem no padrão americano, com exceção da descrição do clima. Sendo assim é necessário fazer a conversão de Fahrenheit para Celsius e alterar a data para o padrão brasileiro.

// weather é o objeto retornado do endpoint
const convertedData = {
    date: new Date(weather.date).toLocaleDateString('pt-BR'),
    temp: (weather.temp - 273.15).toFixed(2),
    tempMax: (weather.tempMax - 273.15).toFixed(2),
    tempMin: (weather.tempMin - 273.15).toFixed(2)
};

Depois dessa conversão o commponente é exportado como html

<div className="weather-info">
    <header className="weather-header">
        <button onClick={onClose} className="close-button">&times;</button>
        <h2>{weather.city}</h2>
    </header>
    <main className="weather-content">
        <p>Data: {convertedData.date}</p>
        <p>Temperatura: {convertedData.temp}°C</p>
        <p>Temp Max: {convertedData.tempMax}°C</p>
        <p>Temp Min: {convertedData.tempMin}°C</p>
        <p>Descrição: {weather.description}</p>
        <img src={`http://openweathermap.org/img/wn/${weather.icon}.png`} alt={weather.description} />
    </main>
</div>
  1. Reenderizando os dados

Exportado como html, agora é possível chamálo na aplicação, mas para controle do usuário caso ele não queira mais ver essa informação é necessário haver um meio de esconder isso.

function renderWeatherInfo() {
    if (!weather) return null; // se não houver dados, retornar null
    if (!isWeatherVisible) return null; // se isWeatherVisible for false, retornar null

    // montando componente
    return (
        <div className= "weather-popup" >
            <WeatherInfo 
            weather={ weather }
            onClose = { handleCloseWeather } />
        </div>
    );
}

Com isso o usuário consegue fechar o popup com os dados do clima e continuar pesquisando. Quando uma outra cidade for pesquisada, o componente voltará a aparecer com os novos dados.

About

Teste de Proficiência em Programação

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published