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

Desafio Técnico - Rafael Fragoso #183

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d498e2a
:tada: (setup) initial commit
orafaelfragoso Jun 11, 2024
f5f5b0c
:wrench: (jest) adds jest to the project
orafaelfragoso Jun 11, 2024
b52c016
:sparkles: (services) adds the ability to pull images from bing serve…
orafaelfragoso Jun 11, 2024
ad27020
:white_check_mark: (services) adds tests for bing service
orafaelfragoso Jun 11, 2024
8b731f1
:sparkles: (forecast) add route and service to get forecast
orafaelfragoso Jun 11, 2024
0e6c61f
:recycle: (forecast) change endpoint method to POST
orafaelfragoso Jun 11, 2024
8523e6d
:sparkles: (forecasts) pull from correct endpoint and transpile data
orafaelfragoso Jun 11, 2024
fcea6af
:sparkles: (coordinates) add coordinates endpoint and tests
orafaelfragoso Jun 12, 2024
5ef4be0
:lock: (input) add sanitization utility to sanitize input
orafaelfragoso Jun 13, 2024
face28b
:sparkles: (hooks) add hooks for geolocation, geomapping and fetching…
orafaelfragoso Jun 13, 2024
803fa45
:recycle: (services) add icon prop to the response
orafaelfragoso Jun 13, 2024
dc0bbc5
:sparkles: (components) add weather and widget components connecting …
orafaelfragoso Jun 13, 2024
25f0ab8
:white_check_mark: (forecast) fix forecast testing to accomodate the …
orafaelfragoso Jun 13, 2024
d564eb5
:rotating_light: (types) fix types for commitlint and forecast test
orafaelfragoso Jun 13, 2024
73706dd
:art: (mobile) make component responsive
orafaelfragoso Jun 13, 2024
990351c
:bug: (mobile) fix mobile scroll
orafaelfragoso Jun 13, 2024
5f425d2
:white_check_mark: (tests) add tests for WeatherWidget and useForecast
orafaelfragoso Jun 14, 2024
5075e52
:bug: (components) fixed color mapping and improved ui
orafaelfragoso Jun 14, 2024
9199c79
:construction_worker: (docker) add docker and docker-compose
orafaelfragoso Jun 14, 2024
136a996
:recycle: (components) remove console log
orafaelfragoso Jun 14, 2024
f0c01ba
:pencil: (readme) add readme instructions
orafaelfragoso Jun 14, 2024
2fc5e2e
:bug: (mobile) fix scroll on safari and wind direction
orafaelfragoso Jun 14, 2024
afb3c79
:white_check_mark: (forecast) fix forecast test
orafaelfragoso Jun 14, 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
13 changes: 0 additions & 13 deletions .editorconfig

This file was deleted.

2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
OPEN_WEATHER_API_KEY=
OPEN_CAGE_API_KEY=
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", "prettier"]
}
Binary file added .github/cover.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 37 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# 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
.env

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
1 change: 1 addition & 0 deletions .husky/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
npx commitlint --edit $1
1 change: 1 addition & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
npm run lint-staged
2 changes: 2 additions & 0 deletions .husky/pre-push
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
npm run test
npm run build
4 changes: 4 additions & 0 deletions .lintstagedrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"*.{js,jsx,ts,tsx}": ["prettier --write", "eslint --fix", "eslint"],
"*.{json,md,yml}": ["prettier --write"]
}
8 changes: 8 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"trailingComma": "es5",
"semi": true,
"tabWidth": 2,
"singleQuote": true,
"jsxSingleQuote": true,
"printWidth": 120
}
25 changes: 25 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Stage 1: Build
FROM node:18-alpine AS builder

WORKDIR /app

COPY package.json package-lock.json ./
RUN npm install

COPY . .
RUN npm run build

FROM node:18-alpine AS runner

WORKDIR /app

ENV NODE_ENV=production

COPY --from=builder /app/package.json /app/package-lock.json ./
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/public ./public
COPY --from=builder /app/node_modules ./node_modules

EXPOSE 3000

CMD ["npm", "start"]
13 changes: 13 additions & 0 deletions Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Stage 1: Base
FROM node:18-alpine AS base

WORKDIR /app

COPY package.json package-lock.json ./
RUN npm install

COPY . .

EXPOSE 3000

CMD ["npm", "run", "dev"]
129 changes: 88 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,59 +1,106 @@
# <img src="https://avatars1.githubusercontent.com/u/7063040?v=4&s=200.jpg" alt="HU" width="24" /> Charlie Challenge
### Projeto NextJS 14 - Desafio de Codificação

[[English](README.md) | [Portuguese](README.pt.md)]
![Previsão do tempo](./.github/cover.jpeg)

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.
## Visão Geral

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_.
Este projeto foi desenvolvido utilizando NextJS 14 e React, com o objetivo de criar uma aplicação de previsão do tempo com uma interface mais apelativa e clean. Várias decisões técnicas foram tomadas para otimizar o desempenho, acessibilidade e usabilidade da aplicação.

The Bing highlight image should be used as the background. Forecasts for: today, tomorrow and the day after tomorrow should be shown.
[Confira o projeto rodando.](https://challenge-charlie-mocha.vercel.app/)

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.
## Decisões Técnicas

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).
- **Visual Apelativo**: O visual foi aprimorado para ser mais atraente e clean.
- **Rotas no Server**: Todos os serviços externos possuem rotas no servidor para consumo pelo frontend, resolvendo problemas de CORS.
- **Imagem do Bing**: Utiliza-se um efeito de vidro (glass effect) para desfocar a imagem do Bing, focando a atenção no widget de previsão do tempo.
- **Utilitários**: Foram criados utilitários para sanitização de input e conversão de temperatura, evitando requisições adicionais.
- **Server-Side Rendering (SSR)**: Imagem e localização de placeholder são obtidas via SSR com componentes de servidor, garantindo que tudo esteja pronto na tela para o usuário.
- **Testes**: Testes foram escritos para cada tipo de arquivo, embora não haja 100% de cobertura para acelerar a entrega.
- **Hooks de Commit e Push**: Utilização do Husky, commit-lint e commitzen para validar linter, rodar testes e build antes de commits ou push, garantindo qualidade e padronização.
- **Validação com Zod**: Variáveis de ambiente são validadas com Zod, notificando o desenvolvedor caso estejam faltando.
- **Boas Práticas de React**: Componentes otimizados, lógica movida para custom hooks e uso de composição.
- **Acessibilidade**: A aplicação foi desenvolvida com foco na acessibilidade.
- **Interface de Monitoramento Genérica**: Foi criada uma interface genérica para ferramentas de monitoramento.

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.
## Melhorias Futuras

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.
- **Testes**: Escrever mais testes e implementar testes e2e com Cypress ou Playwright.
- **Estados de Loading e Erro**: Adicionar estados de carregamento e erro nos componentes.
- **Gerenciamento de Estado**: Utilizar Zustand ou Context API para projetos mais complexos.
- **UI**: Adotar Shadcn para criação da interface em vez de desenvolver manualmente.
- **Desempenho**: Revisar componentes para identificar gargalos de renderização.
- **Monitoramento**: Implementar monitoramento no middleware do Next e em outros pontos.
- **Caching**: Melhorar o caching das requisições.

Icons can be found at http://www.alessioatzeni.com/meteocons/.
## Rodando o Projeto

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.
### Pré-requisitos

## Requirements
- Node.js
- Docker
- docker-compose

- 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
### Configuração

## Evaluation criteria
1. Clone o repositório:

- **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?
```bash
git clone https://github.com/seu-usuario/seu-repositorio.git
cd seu-repositorio
```

## Doubts
2. Crie o arquivo `.env` utilizando o `.env.example` como modelo e preencha as variáveis necessárias. Entre em contato para obter os valores específicos, se necessário.

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!
### Usando Docker

Godspeed! ;)
#### Desenvolvimento

<p align="center">
<img src="ca.jpg" alt="Challange accepted" />
</p>
Para rodar o ambiente de desenvolvimento com Docker, utilize o comando:

```bash
docker-compose -f docker-compose.dev.yml up --build
```

#### Produção

Para rodar o ambiente de produção com Docker, utilize o comando:

```bash
docker-compose up --build
```

### Usando NPM

1. Instale as dependências:

```bash
npm install
```

2. Inicie o servidor de desenvolvimento:
```bash
npm run dev
```

## Estrutura do Projeto

A estrutura do projeto é organizada da seguinte forma:

```
/src
/app # Rotas da API e app
/components # Componentes React
/utils # Utilitários
/hooks # Custom Hooks
/assets # Fontes
/services # Serviços de API
```

## Contribuindo

Para contribuir com este projeto, siga os passos abaixo:

1. Faça as suas modificações
2. Adicione suas modificações ao stage do git (`git add .`).
3. Commit suas alterações com o commit-lint (`npm run commit`).
4. Push para a branch (`git push origin feature/nova-feature`).
60 changes: 0 additions & 60 deletions README.pt.md

This file was deleted.

Binary file removed ca.jpg
Binary file not shown.
35 changes: 35 additions & 0 deletions commitlint.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const pkg = require('./package.json');

interface CommitMessageContext {
raw: string;
}

// Check if the user has configured the package to use conventional commits.
const isConventional = pkg.config ? pkg.config['cz-emoji']?.conventional : false;

// Regex for default and conventional commits.
const RE_DEFAULT_COMMIT =
/^(?::.*:|(?:\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff]))\s(?<emoji>\((?<scope>.*)\)\s)?.*$/gm;
const RE_CONVENTIONAL_COMMIT =
/^^(?<type>\w+)(?:\((?<scope>\w+)\))?\s(?<emoji>:.*:|(?:\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff]))\s.*$/gm;

module.exports = {
rules: {
'cz-emoji': [2, 'always'],
},
plugins: [
{
rules: {
'cz-emoji': ({ raw }: CommitMessageContext) => {
const isValid = isConventional ? RE_CONVENTIONAL_COMMIT.test(raw) : RE_DEFAULT_COMMIT.test(raw);

const message = isConventional
? `Your commit message should follow conventional commit format.`
: `Your commit message should be: <emoji> (<scope>)?: <subject>`;

return [isValid, message];
},
},
},
],
};
17 changes: 17 additions & 0 deletions docker-compose.dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
version: '3.8'

services:
app:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- '3000:3000'
volumes:
- .:/app
- /app/node_modules
environment:
- NODE_ENV=development
- PORT=3000
env_file:
- .env
13 changes: 13 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: '3.8'

services:
app:
build:
context: .
ports:
- '3000:3000'
environment:
- NODE_ENV=production
- PORT=3000
env_file:
- .env
Loading