Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Entrega | Teste Técnico - Challenge Charlie | Eduardo Zaqueu #181

Open
wants to merge 34 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
e242b79
feat: initial commit containing basic folder structure
May 25, 2024
4b674cd
feat: clean public folder
May 25, 2024
60bec9b
feat: early input & components development
May 25, 2024
f8de055
feat: Add early WeatherBox component layout
May 25, 2024
4188706
feat: add better input file logic and add services & api routes
May 25, 2024
5fac5ab
feat: better utils functions, add loader and all fetch functions full…
May 25, 2024
e876fe4
feat: add all icons, correct typying for weather and better SearchInp…
May 25, 2024
40d2111
feat: add button to change celsius to fahrenheit
May 26, 2024
649acc8
feat: add responsiviness, adjust icons and general components sizing
May 26, 2024
f495244
style: refactors handleBackgroundColor so it returns a gradient effect
May 26, 2024
0314c5e
chore: add Dockerfile and docker-compose.yml for containerization
May 26, 2024
fe6409a
feat: add CurrentTemperature component, adjust types and implement ne…
May 26, 2024
dae5e57
feat: adjusts on background function, general stylying
May 26, 2024
98c93c1
docs: add README and github folder containing logo
May 26, 2024
e041303
docs: README adjust
May 26, 2024
5afccd1
docs: updated README with deploy and demo
May 26, 2024
7dec196
chore/docs: small README adjust, console.log removal and favicon add
May 26, 2024
2ee2e4c
docs: README adjust
May 26, 2024
e129192
docs: remove double https from README deploy link
May 26, 2024
94cbf32
feat: search system now returns better results as it also accepts sta…
May 27, 2024
9b3f0a7
feat: merge fetchBackground useEffect into a previous one to reduce u…
May 27, 2024
725f1f0
docs: update demo
May 27, 2024
7bf7471
refactor: routes and utils functions refactor and better error handling
May 28, 2024
ca1c9a9
test: add api route handlers testing and some file corrections for co…
May 28, 2024
9171542
test: add components tests and some minor file adjusts
May 28, 2024
c482b6f
refactor: remove placeholder unecessary logic/state
May 29, 2024
a77d7c0
feat: add tip/error handler and feature to WeatherBox component and m…
May 29, 2024
c964676
docs: updated README
May 29, 2024
815899b
test: add utils tests, covering both services and helper functions
May 29, 2024
860969c
fix: handleNextDaysWeather and currentWeather not reflecting real-tim…
May 29, 2024
fae463d
feat: update on utils weather related functions and its related tests
May 29, 2024
385b493
feat: adjusts handleTodaysWeather function to filter the next dt_txt …
May 29, 2024
d47dc31
fix: adjust handleNextDaysWeather to return an empty array in case of…
May 29, 2024
d86da03
fix: removed lang=pt-br parameter from openWeather api
Jun 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Dockerfile
.dockerignore
node_modules
npm-debug.log
README.md
.next
.git
13 changes: 0 additions & 13 deletions .editorconfig

This file was deleted.

2 changes: 2 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
OPENWEATHER_API_KEY=772920597e4ec8f00de8d376dfb3f094
OPENCAGE_API_KEY=c94807a09e26484bb65d0f8cd98eb75b
3 changes: 3 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}
36 changes: 36 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
19 changes: 19 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Development stage
FROM node:18 AS dev
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
ENV NODE_ENV=dev
CMD ["npm", "run", "dev"]

# Production stage
FROM node:18 AS prod
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
ENV NODE_ENV=prod
EXPOSE 3000
CMD ["npm", "start"]
12 changes: 12 additions & 0 deletions FixJSDOMEnvironment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import JSDOMEnvironment from 'jest-environment-jsdom'

export default class FixJSDOMEnvironment extends JSDOMEnvironment {
constructor(...args: ConstructorParameters<typeof JSDOMEnvironment>) {
super(...args)

this.global.fetch = fetch
this.global.Headers = Headers
this.global.Request = Request
this.global.Response = Response
}
}
128 changes: 69 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,59 +1,69 @@
# <img src="https://avatars1.githubusercontent.com/u/7063040?v=4&s=200.jpg" alt="HU" width="24" /> Charlie Challenge

[[English](README.md) | [Portuguese](README.pt.md)]

Build a responsive microsite to display the weather forecast at the locations given in the white text box (in the [example](./exemplo.jpg) image is where "Rio de Janeiro, Rio de Janeiro" appears. This text box should be an `input`, where the user can change the location. With the change of location, the weather forecast information for the new location must be loaded.

Once the page is opened, the user's geographic coordinates must be collected by the browser API to discover the city name via _reverse geocode_.

The Bing highlight image should be used as the background. Forecasts for: today, tomorrow and the day after tomorrow should be shown.

Note that there is a gradient superimposed on the original image, in fact this color reflects the current temperature of the place searched for the three dates. For temperatures below 15ºC, shades of blue should be used, for temperatures above 35ºC, shades of red should be used and shades of yellow should be used for other temperatures. When there is no chosen location, shades of gray should be used as the basis for the gradient. If the user clicks on any temperature, the temperatures should be changed from Celsius to Fahrenheit or from Fahrenheit to Celsius.

The background image URL should be extracted from the [Bing API](https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=pt-US).

To consult the weather forecast, use the one from [OpenWeather](http://api.openweathermap.org/data/2.5/weather?q={{location_name}}&APPID=772920597e4ec8f00de8d376dfb3f094) informing the name of the location instead of ` {{location_name}}` using app id `772920597e4ec8f00de8d376dfb3f094`. If necessary, create a new account.

To convert latitude and longitude to a location use [OpenCage](https://api.opencagedata.com/geocode/v1/json?q={{latitude}},{{longitude}}&key=c63386b4f77e46de817bdf94f552cddf&language=en) using the API key `c63386b4f77e46de817bdf94f552cddf`. If necessary, create a new account.

Icons can be found at http://www.alessioatzeni.com/meteocons/.

The layout must be followed, but you can suggest improvements. Describe these improvements in the README and why. You get extra points if these improvements are positive, or lose points otherwise.

## Requirements

- Preferably do it in React, but you can use other libraries or frameworks (Angular, Vue.js, etc) or pure JavaScript (Vanilla JS).
- For the style sheet, you can use whatever you prefer (CSS, SASS, LESS, CSS Modules, CSS-in-JS, etc).
- Preferably use Webpack. If you prefer, you can use [create-react-app](https://github.com/facebook/create-react-app) or similar. Doing your own Webpack setup gives you extra points.
- It is interesting that your application is ready for production. Create in Docker a `stage` for production and one for development of extra points.
- Fork this challenge and create your project (or workspace) using your version of that repository, as soon as you finish the challenge, submit a _pull request_.
- If you have any reason not to submit a _pull request_, create a private repository on Github, do every challenge on the **master** branch and don't forget to fill in the `pull-request.txt` file. As soon as you finish your development, add the user [`automator-hurb`](https://github.com/automator-hurb) to your repository as a contributor and make it available for at least 30 days. **Do not add the `automator-hurb` until development is complete.**
- If you have any problem creating the private repository, at the end of the challenge fill in the file called `pull-request.txt`, compress the project folder - including the `.git` folder - and send it to us by email.
- The code needs to run inside a Docker container.
- To run your code, all you need to do is run the following commands:
- git clone \$your-fork
- cd \$your-fork
- command to install dependencies
- command to run the application

## Evaluation criteria

- **Organization of code**: Separation of modules, view and model, back-end and front-end
- **Clarity**: Does the README explain briefly what the problem is and how can I run the application?
- **Assertiveness**: Is the application doing what is expected? If something is missing, does the README explain why?
- **Code readability** (including comments)
- **Security**: Are there any clear vulnerabilities?
- **Test coverage** (We don't expect full coverage)
- **History of commits** (structure and quality)
- **UX**: Is the interface user-friendly and self-explanatory? Is the API intuitive?
- **Technical choices**: Is the choice of libraries, database, architecture, etc. the best choice for the application?

## Doubts

Any questions you may have, check the [_issues_](https://github.com/HurbCom/challenge-charlie/issues) to see if someone hasn't already and if you can't find your answer, open one yourself. new issue!

Godspeed! ;)

<p align="center">
<img src="ca.jpg" alt="Challange accepted" />
</p>
<img src="https://github.com/zaqueu-1/challenge-charlie/blob/master/github/logo.png" width='50' height='50' alt="logo">

## Challenge Charlie | Teste Técnico

O projeto aqui encontrado se trata de um desafio técnico e foi desenvolvido com base em requisitos pré-estabelecidos pela empresa.

O objetivo é exibir a previsão do tempo de acordo com a localização atual do usuário usando a [API de geolocalização](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API) para coletar coordenadas, a [OpenCageAPI](https://opencagedata.com/api) para identificar a localização e [OpenWeatherAPI](https://openweathermap.org/api) para retornar os dados de clima do dia atual e dos dois seguintes.

Utilizei as seguintes tecnologias:

![TypeScript](https://img.shields.io/badge/typescript-%23007ACC.svg?style=for-the-badge&logo=typescript&logoColor=white)

![Next JS](https://img.shields.io/badge/Next-black?style=for-the-badge&logo=next.js&logoColor=white)

![TailwindCSS](https://img.shields.io/badge/tailwindcss-%2338B2AC.svg?style=for-the-badge&logo=tailwind-css&logoColor=white)

## Deploy
https://challenge-charlie-eduardo-zaqueu.vercel.app/

## Demonstração
![demo](https://github.com/zaqueu-1/challenge-charlie/blob/master/github/demo.gif)

## Rodar o projeto localmente
Os passos a seguir são para clonar e rodar o projeto localmente, em modo de desenvolvimento:
```bash
git clone https://github.com/zaqueu-1/challenge-charlie.git
```
```bash
cd challenge-charlie
```
```bash
npm install
```
```bash
npm run dev
```
## Rodar o projeto via Docker
Também é possível rodar o projeto através de um contêiner pelo Docker. Para isso, siga os seguintes comandos após clonar e estar na raiz do projeto:
- Iniciar em ambiente de produção
```bash
docker-compose up --build prod
```
O projeto estará rodando na porta 3001 em http://localhost:3001
- Iniciar em ambiente de desenvolvimento
```bash
docker-compose up --build dev
```
O projeto estará rodando na porta 3000 em http://localhost:3000

## Testes
Os testes foram realizados usando Jest e React Testing Library. Para rodá-los, execute o seguinte comando:
```bash
npm run test
```
## Estrutura do Projeto
Abaixo, algumas informações sobre minhas escolhas e tomadas de decisão durante o andamento do projeto:

* Optei por utilizar o próprio ícone de bússola como loader, a fim de manter a simplicidade da interface;
* Utilizei [Route Handlers](https://nextjs.org/docs/app/building-your-application/routing/route-handlers) para criar rotas para o consumo das APIs requeridas no desafio. Dessa forma é possível fazer requisições com todos os métodos HTTP, facilitando também a criação dos serviços e suas respectivas funções;
* O input realiza a busca da localidade ao pressionar o Enter, removendo a necessidade de um botão adicional na interface. Além disso, incluí uma função simples de limpeza do input ao clicar na div que o contem, facilitando a inserção de uma nova localidade;
* Para a unidade de temperatura, além de torná-la clicável, adicionei uma legenda contendo a unidade oposta à atual. Ao ser clicada, ela alterna a unidade de todas as ocorrências de temperatura na página, assim como a própria legenda;
* Incluí no input uma renderização condicional que exibe 'Buscando...' enquanto a API não retorna a localidade;
* Mantive a .env no repositório pelo fato de a chave de API fornecida no desafio para a OpenCage estar inválida. Criei minha própria conta e inseri minha chave, que servirá para os eventuais testes da equipe de avaliação;
* Incluí uma sutil faixa abaixo do input que exibe uma mensagem de erro caso a API não encontre a localização desejada. Na ausência de erros, ela irá exibir uma dica pro usuário, informando que é possível separar estado e cidade por vírgula caso a busca não retorne o resultado esperado.

## Autor

- [@zaqueu-1](https://www.github.com/zaqueu-1)
Acesse também meu [LinkedIn](https://linkedin.com/in/zaqueu1) e dê uma olhada em meu [portfolio](https://zaqueu.tech)!
60 changes: 0 additions & 60 deletions README.pt.md

This file was deleted.

Binary file removed ca.jpg
Binary file not shown.
25 changes: 25 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
version: '3'
services:
dev:
build:
context: .
target: dev
container_name: challenge-eduardo-zaqueu-dev
ports:
- "3000:3000"
volumes:
- .:/app
environment:
- NODE_ENV=dev
restart: always

prod:
build:
context: .
target: prod
container_name: challenge-eduardo-zaqueu-prod
ports:
- "3001:3000"
environment:
- NODE_ENV=prod
restart: always
Binary file removed exemplo.jpg
Binary file not shown.
Binary file added github/demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added github/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Config } from 'jest'
import nextJest from 'next/jest.js'

const createJestConfig = nextJest({
dir: './',
})

const config: Config = {
coverageProvider: 'v8',
testEnvironment: './FixJSDOMEnvironment.ts',
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1',
},
}

export default createJestConfig(config)
1 change: 1 addition & 0 deletions jest.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import '@testing-library/jest-dom'
4 changes: 4 additions & 0 deletions next.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/** @type {import('next').NextConfig} */
const nextConfig = {};

export default nextConfig;
Loading