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

Kawan - Desafio de Front-end #12

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 9 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
root = true

[*]
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
end_of_line = lf
1 change: 1 addition & 0 deletions .eslintcache
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"/Users/kawan/Desktop/frontend-challenge/src/index.tsx":"1","/Users/kawan/Desktop/frontend-challenge/src/pages/Dashboard/styles.ts":"2","/Users/kawan/Desktop/frontend-challenge/src/pages/Dashboard/index.tsx":"3","/Users/kawan/Desktop/frontend-challenge/src/components/Select/index.tsx":"4","/Users/kawan/Desktop/frontend-challenge/src/components/Select/styles.ts":"5","/Users/kawan/Desktop/frontend-challenge/src/App.tsx":"6","/Users/kawan/Desktop/frontend-challenge/src/styles/global.ts":"7","/Users/kawan/Desktop/frontend-challenge/src/utils/getValidationErrors.ts":"8","/Users/kawan/Desktop/frontend-challenge/src/components/InputMask/index.tsx":"9","/Users/kawan/Desktop/frontend-challenge/src/components/InputMask/styles.ts":"10","/Users/kawan/Desktop/frontend-challenge/src/components/Input/styles.ts":"11","/Users/kawan/Desktop/frontend-challenge/src/components/Input/index.tsx":"12","/Users/kawan/Desktop/frontend-challenge/src/services/api.ts":"13","/Users/kawan/Desktop/frontend-challenge/src/components/UpdateDialogButton/index.tsx":"14"},{"size":267,"mtime":1610775743791,"results":"15","hashOfConfig":"16"},{"size":4294,"mtime":1611249977822,"results":"17","hashOfConfig":"16"},{"size":4855,"mtime":1611257380219,"results":"18","hashOfConfig":"16"},{"size":1202,"mtime":1611158307240,"results":"19","hashOfConfig":"16"},{"size":519,"mtime":1611159954370,"results":"20","hashOfConfig":"16"},{"size":218,"mtime":1610775747858,"results":"21","hashOfConfig":"16"},{"size":359,"mtime":1610676658432,"results":"22","hashOfConfig":"16"},{"size":347,"mtime":1610996242859,"results":"23","hashOfConfig":"16"},{"size":911,"mtime":1611026921699,"results":"24","hashOfConfig":"16"},{"size":378,"mtime":1611027807283,"results":"25","hashOfConfig":"16"},{"size":317,"mtime":1611248406796,"results":"26","hashOfConfig":"16"},{"size":749,"mtime":1611248413635,"results":"27","hashOfConfig":"16"},{"size":116,"mtime":1611245191705,"results":"28","hashOfConfig":"16"},{"size":2849,"mtime":1611258362997,"results":"29","hashOfConfig":"16"},{"filePath":"30","messages":"31","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"hj48le",{"filePath":"32","messages":"33","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"34","messages":"35","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"36","messages":"37","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"38","messages":"39","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"40","messages":"41","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"42","messages":"43","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"44"},{"filePath":"45","messages":"46","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"47"},{"filePath":"48","messages":"49","errorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"50","messages":"51","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"52","messages":"53","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"54","messages":"55","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"56","messages":"57","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"58","messages":"59","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},"/Users/kawan/Desktop/frontend-challenge/src/index.tsx",[],"/Users/kawan/Desktop/frontend-challenge/src/pages/Dashboard/styles.ts",[],"/Users/kawan/Desktop/frontend-challenge/src/pages/Dashboard/index.tsx",[],"/Users/kawan/Desktop/frontend-challenge/src/components/Select/index.tsx",[],"/Users/kawan/Desktop/frontend-challenge/src/components/Select/styles.ts",[],"/Users/kawan/Desktop/frontend-challenge/src/App.tsx",[],"/Users/kawan/Desktop/frontend-challenge/src/styles/global.ts",[],["60","61","62","63","64"],"/Users/kawan/Desktop/frontend-challenge/src/utils/getValidationErrors.ts",["65"],"import { ValidationError } from 'yup';\n\ninterface Error {\n [key: string]: string;\n}\n\nfunction getValidationError(errors: ValidationError): Error {\n const validationError: Error = {};\n\n errors.inner.forEach(error => {\n validationError[error.path as any] = error.message;\n });\n\n return validationError;\n}\n\nexport default getValidationError;\n","/Users/kawan/Desktop/frontend-challenge/src/components/InputMask/index.tsx",["66","67"],"/Users/kawan/Desktop/frontend-challenge/src/components/InputMask/styles.ts",[],"/Users/kawan/Desktop/frontend-challenge/src/components/Input/styles.ts",[],"/Users/kawan/Desktop/frontend-challenge/src/components/Input/index.tsx",[],"/Users/kawan/Desktop/frontend-challenge/src/services/api.ts",[],"/Users/kawan/Desktop/frontend-challenge/src/components/UpdateDialogButton/index.tsx",["68"],{"ruleId":"69","replacedBy":"70"},{"ruleId":"71","replacedBy":"72"},{"ruleId":"73","replacedBy":"74"},{"ruleId":"75","replacedBy":"76"},{"ruleId":"77","replacedBy":"78"},{"ruleId":"79","severity":1,"message":"80","line":11,"column":35,"nodeType":"81","messageId":"82","endLine":11,"endColumn":38,"suggestions":"83"},{"ruleId":"79","severity":1,"message":"80","line":21,"column":21,"nodeType":"81","messageId":"82","endLine":21,"endColumn":24,"suggestions":"84"},{"ruleId":"79","severity":1,"message":"80","line":24,"column":23,"nodeType":"81","messageId":"82","endLine":24,"endColumn":26,"suggestions":"85"},{"ruleId":"86","severity":1,"message":"87","line":64,"column":9,"nodeType":"88","messageId":"89","endLine":64,"endColumn":20},"lines-around-directive",["90"],"global-require",[],"no-buffer-constructor",[],"no-new-require",[],"no-path-concat",[],"@typescript-eslint/no-explicit-any","Unexpected any. Specify a different type.","TSAnyKeyword","unexpectedAny",["91","92"],["93","94"],["95","96"],"no-console","Unexpected console statement.","MemberExpression","unexpected","padding-line-between-statements",{"messageId":"97","fix":"98","desc":"99"},{"messageId":"100","fix":"101","desc":"102"},{"messageId":"97","fix":"103","desc":"99"},{"messageId":"100","fix":"104","desc":"102"},{"messageId":"97","fix":"105","desc":"99"},{"messageId":"100","fix":"106","desc":"102"},"suggestUnknown",{"range":"107","text":"108"},"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct.","suggestNever",{"range":"107","text":"109"},"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of.",{"range":"110","text":"108"},{"range":"110","text":"109"},{"range":"111","text":"108"},{"range":"111","text":"109"},[254,257],"unknown","never",[573,576],[660,663]]
6 changes: 6 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
**/*.js
/*.js
node_modules
build
/src/react-app-env.d.ts
/src/reportWebVitals.ts
62 changes: 62 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"env": {
"browser": true,
"es2021": true
},
"extends": [
"airbnb",
"prettier/@typescript-eslint",
"plugin:prettier/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended"

],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": [
"prettier",
"react-hooks",
"react",
"@typescript-eslint"
],
"rules": {
"object-curly-newline": "off",
"arrow-parens": "off",
"react/jsx-props-no-spreading": "off",
"react/prop-types": "off",
"no-use-before-define": "off",
"prettier/prettier": "error",
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
"react/jsx-filename-extension": [
1,
{
"extensions": [
".tsx"
]
}
],
"import/prefer-default-export": "off",
"camelcase": "off",
"@typescript-eslint/ban-types": "off",
"import/extensions": [
"error",
"ignorePackages",
{
"ts": "never",
"tsx": "never"
}
]
},
"settings": {
"import/resolver": {
"typescript": {}
}
}
}
23 changes: 23 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
99 changes: 43 additions & 56 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,57 +1,44 @@
# Desafio de Frontend

<img src="./img/logo-clubpetro.png"
alt="Clubpetro" width="300">

- [Descrição](#descrição)
- [O Desafio](#o-desafio)
- [Requisitos Obrigatórios](#requisitos-obrigatórios)
- [Bônus](#bônus)
- [Submissão e Prazo de Entrega](#submissão-e-prazo-de-entrega)

## Descrição

Este desafio tem como objetivo avaliar as habilidades técnicas do canditado a vaga de desenvolvedor frontend no Clubpetro.

#### O Desafio

O desafio consiste em desenvolver um sistema que permita o CRUD de lugares para se conhecer ao redor do mundo. Como na imagem a seguir:

<img src="./img/challenge.png" alt="Desafio" >

O Sistema deverá conter um formulário com 3 campos:

- País: um select contendo a lista de todos os países existentes;
- Local: um input para que o usuário digite o local que ele deseja conhecer no país selecionado;
- Meta: um input para que o usuário digite a o mês e o ano que ele pretende visitar o local em questão.

Quando o usuário clicar em "Adicionar", o formulário deverá ser resetado e o local deverá aparecer na listagem dos cards, como mostrado na imagem acima.

#### Requisitos Obrigatórios

> Requisitos que serão avaliados no desafio.

- O Sistema deverá ser desenvolvido em typescript utilizando a biblioteca [React](https://pt-br.reactjs.org/);
- O Layout apresentado na imagem acima deverá ser fielmente seguido e pode ser encontrado no [Figma](https://www.figma.com/file/IC0xt3K3X21rLEfLRQ3mpl/Lugares-que-quero-conhecer?node-id=0%3A1);
- O CRUD poderá ser gerenciado pelo estado no React;
- Apenas o Local e Meta poderão ser editados e a edição do card deverá ser feita de acordo com a criatividade do canditado, não tendo um layout específico para esta ação;
- O Sistema deverá ser desenvolvido utilizando [React Hooks](https://pt-br.reactjs.org/docs/hooks-intro.html);
- O Sistema deverá ser integrado à API [Rest Countries](https://restcountries.eu/rest/v2/all) para a listagem dos países. Esta conta com a imagem da bandeira e a tradução do nome do país para Português;
- A biblioteca [react-input-mask](https://www.npmjs.com/package/react-input-mask) deverá ser utilizada para colocar uma mascara no input de "Meta" no formato mm/aaaa;
- O Sistema deverá ser responsivo;
- O candidato deverá adicionar ao projeto uma explicação de como executar a aplicação.

#### Bônus

> Requisitos que não são obrigatórios mas podem te deixar em vantagem com relação aos outros candidatos.

- [Material-UI](https://material-ui.com/pt/);
- [Styled Components](https://styled-components.com/);
- Testes automatizados;
- Utilização da biblioteca [json-server](https://www.npmjs.com/package/json-server) para o CRUD.

### Submissão e Prazo de entrega

- O canditado deverá realizar um fork deste repositório e submeter o código no mesmo;
- O prazo de entrega para este desafio é de 2 (duas) semanas, contando a partir do dia em que o candidato recebeu o email com o link do repositório;
- Ao finalizar o desafio, o candidato deverá enviar um email para [email protected] contendo o link do seu PR.
![desafio de frontend](https://raw.githubusercontent.com/Kwan13/frontend-challenge/master/src/assets/capa.png)
### Tecnologias:

- Typescript
- ReactJS
- Styled-Components
- Material-UI
- json-server


### Instruções:
Acesse o diretório raiz do projeto e utilize os comandos abaixo para baixar as dependências e startar o projeto respectivamente.

1. Para baixar as dependências do projeto utilize os comandos:
```
yarn
```
*ou*
```
npm install
```
2. Após efetuar o download das dependências do projeto inicie o backend em seguida o front-end:

_**para inicializar o backend:**_

```
yarn dev:server
```
*ou*
```
npm run dev:server
```


_**para inicializar o front-end:**_

```
yarn start
```
*ou*
```
npm run start
```
1 change: 1 addition & 0 deletions debug.log
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[0114/194120.331:ERROR:directory_reader_win.cc(43)] FindFirstFile: O sistema n�o pode encontrar o caminho especificado. (0x3)
Binary file removed img/challenge.png
Binary file not shown.
Binary file removed img/logo-clubpetro.png
Binary file not shown.
68 changes: 68 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"name": "my-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"@material-ui/core": "^4.11.2",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"@types/jest": "^26.0.15",
"@types/node": "^12.0.0",
"@types/react": "^16.9.53",
"@types/react-dom": "^16.9.8",
"@unform/core": "^2.1.3",
"@unform/web": "^2.1.3",
"axios": "^0.21.1",
"polished": "^4.0.5",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-icons": "^4.1.0",
"react-input-mask": "^2.0.4",
"react-scripts": "4.0.1",
"react-select": "^3.2.0",
"styled-components": "^5.2.1",
"typescript": "^4.0.3",
"uuid": "^8.3.2",
"web-vitals": "^0.2.4",
"yup": "^0.32.8"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"dev:server": "json-server --watch server.json --port 3333"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@types/react-input-mask": "^3.0.0",
"@types/react-select": "^3.1.2",
"@types/styled-components": "^5.1.7",
"@types/uuid": "^8.3.0",
"@typescript-eslint/eslint-plugin": "^4.13.0",
"@typescript-eslint/parser": "^4.13.0",
"eslint": "^7.18.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-config-prettier": "^7.1.0",
"eslint-import-resolver-typescript": "^2.3.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-react": "^7.21.5",
"eslint-plugin-react-hooks": "^4",
"json-server": "^0.16.3",
"prettier": "^2.2.1"
}
}
5 changes: 5 additions & 0 deletions prettier.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
singleQuote: true,
trailingComma: 'all',
arrowParens: 'avoid',
}
19 changes: 19 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<link rel="preconnect" href="https://fonts.gstatic.com">
<!-- <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet"> -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
<title>React App</title>
</head>

<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>

</html>
3 changes: 3 additions & 0 deletions public/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
74 changes: 74 additions & 0 deletions server.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
{
"countries": [
{
"id": "ac8020b6-e07f-4b91-bf1e-2141764eb180",
"flag": "https://restcountries.eu/data/esp.svg",
"country": "Espanha",
"local": "Madrid",
"date": "10/2021"
},
{
"id": "7fcfd414-bd08-4d6c-aa89-f17c38b4d330",
"flag": "https://restcountries.eu/data/rus.svg",
"country": "Rússia",
"local": "Moscou",
"date": "09/2021"
},
{
"id": "78c6837e-c944-4a56-aaf7-410a535a2cd0",
"flag": "https://restcountries.eu/data/swe.svg",
"country": "Suécia",
"local": "Lund",
"date": "08/2021"
},
{
"id": "dd5ad68f-7854-4d83-8d64-b5bb33b98f59",
"flag": "https://restcountries.eu/data/jpn.svg",
"country": "Japão",
"local": "Tokyo",
"date": "07/2020"
},
{
"id": "246f1d79-c112-4e55-b9a8-d5e7aa244c66",
"flag": "https://restcountries.eu/data/pol.svg",
"country": "Polônia",
"local": "GDANSK",
"date": "06/2021"
},
{
"id": "95728e6e-32af-47e7-8751-84b28db63404",
"flag": "https://restcountries.eu/data/prt.svg",
"country": "Portugal",
"local": "Lisboa",
"date": "05/2021"
},
{
"id": "9194c492-0740-411c-a749-a0a3bff40ad0",
"flag": "https://restcountries.eu/data/usa.svg",
"country": "Estados Unidos",
"local": "Disney World",
"date": "04/2021"
},
{
"id": "e0976045-add4-4980-9707-c2548e044df7",
"flag": "https://restcountries.eu/data/bra.svg",
"country": "Brasil",
"local": "Florianópolis",
"date": "03/2021"
},
{
"id": "b1e5affb-198a-4072-8384-763a33a029ff",
"flag": "https://restcountries.eu/data/bra.svg",
"country": "Brasil",
"local": "Blumenau",
"date": "02/2021"
},
{
"id": "8e896418-44db-48bb-b7f7-5878735397c8",
"flag": "https://restcountries.eu/data/bra.svg",
"country": "Brasil",
"local": "Salvador",
"date": "01/2021"
}
]
}
13 changes: 13 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';

import Dashboard from './pages/Dashboard';
import GlobalStyle from './styles/global';

const App: React.FC = () => (
<>
<Dashboard />
<GlobalStyle />
</>
);

export default App;
Binary file added src/assets/capa.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading