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

Teste Front-end - Le Tip - Victor Machado #2

Open
wants to merge 57 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
3057415
Projeto Vue adicionado
victormachadogp Nov 22, 2024
f8bcac4
Removendo código inicial Vue
victormachadogp Nov 23, 2024
5a74f5f
Definindo estrutura dos componentes
victormachadogp Nov 23, 2024
1febfce
Implementando funcionalidade ao CurrencySelector
victormachadogp Nov 23, 2024
c1c2da2
Adiciona campo de entrada para o total da conta
victormachadogp Nov 23, 2024
97378cc
Altera nome RangeField para RangeInput
victormachadogp Nov 23, 2024
0ea8880
Adiciona input dinâmico - gorjeta e número pessoas
victormachadogp Nov 23, 2024
8c03eea
Adiciona o pacote sass-embedded
victormachadogp Nov 23, 2024
f0077df
Adiciona Pacote axios
victormachadogp Nov 23, 2024
72af70d
Implementa two-way binding (v-model) no inputRange
victormachadogp Nov 23, 2024
045f3db
Adiciona diretorio services e requisição API
victormachadogp Nov 23, 2024
449507f
Adicionar composables para conversão de moeda
victormachadogp Nov 23, 2024
ce5816b
Melhora dinamicamente o CurrencySelector
victormachadogp Nov 23, 2024
b726104
Melhora dinamicamente o CurrencySelector
victormachadogp Nov 23, 2024
d89b8d0
Refatoração: Substituindo select por toggle
victormachadogp Nov 23, 2024
74eb6df
Adicionado estilo inicial no TipCalculator
victormachadogp Nov 24, 2024
f0ab78d
Adiciona espaçamento nos componentes
victormachadogp Nov 24, 2024
641391b
Estilizando rangeInput
victormachadogp Nov 24, 2024
ce1ef58
Removendo titulo e adicionando padding top
victormachadogp Nov 24, 2024
d35f578
Ajusta visibilidade do painel no mobile
victormachadogp Nov 24, 2024
5b9eb14
Diminuindo padding do input
victormachadogp Nov 24, 2024
abb3f42
Alterando estilo do input
victormachadogp Nov 25, 2024
2c978d6
Alterando estilo do toggle
victormachadogp Nov 25, 2024
7414afa
Aplicar estilo negrito em elementos span
victormachadogp Nov 25, 2024
ef4e8cd
Adicionado box shadow e header
victormachadogp Nov 25, 2024
5a3e23d
Atualização README.md
victormachadogp Nov 25, 2024
a86d199
Adicionado slot e alteração do nome componente
victormachadogp Nov 25, 2024
6bcddd7
Merge remote-tracking branch 'origin/frontend-test/victor-machado' in…
victormachadogp Nov 25, 2024
7f31cb5
Nome da classe alterado
victormachadogp Nov 25, 2024
3e6c7ec
Criando componente CurrencyInput
victormachadogp Nov 25, 2024
848bfb8
Criando componente FloatButton
victormachadogp Nov 25, 2024
4b03c9b
Removendo estilos float no TipCalculator
victormachadogp Nov 25, 2024
8b24805
Personaliza exibição do range input
victormachadogp Nov 25, 2024
c9cd715
Removido step do RangeInput
victormachadogp Nov 25, 2024
d446d24
Remove main.css
victormachadogp Nov 25, 2024
4ba4dc3
Estilo base scss adicionado e background images
victormachadogp Nov 25, 2024
61a7a25
Adicionado titulo Le Tip
victormachadogp Nov 25, 2024
233f88e
Alterado estilo do TipCalculator
victormachadogp Nov 25, 2024
329493e
Adicionando Vitest
victormachadogp Nov 26, 2024
f099c05
Testando CurrencySelector
victormachadogp Nov 26, 2024
07c9f43
Testando componente CurrencyInput
victormachadogp Nov 26, 2024
ed6037f
Testando componente RangeInput
victormachadogp Nov 26, 2024
33ab839
Testando service currencyService
victormachadogp Nov 26, 2024
9054d55
Teste integração com API
victormachadogp Nov 26, 2024
7f376a6
Testando ResultsPanel
victormachadogp Nov 26, 2024
c490130
Removendo error do ResultsPanel
victormachadogp Nov 26, 2024
a724351
Alterando SCSS obsoleto
victormachadogp Nov 26, 2024
eb1cf86
Removendo defineProps, defineEmits
victormachadogp Nov 26, 2024
58028fe
Atualizando SASS JS API
victormachadogp Nov 26, 2024
863aeca
Adicionando dotenv para chave API
victormachadogp Nov 26, 2024
c8a3223
Adicionando teste ao TipCalculator
victormachadogp Nov 26, 2024
683ba80
Explicando useCurrencyConverter
victormachadogp Nov 26, 2024
f4cd13f
Removendo border radius no mobile do ResultsPanel
victormachadogp Nov 26, 2024
fbed78d
Removendo dotenv
victormachadogp Nov 26, 2024
5e7ac2c
Update README.md
victormachadogp Nov 26, 2024
6ae7d7a
Adicionando comentario de API
victormachadogp Nov 26, 2024
46e8538
Merge remote-tracking branch 'origin/frontend-test/victor-machado' in…
victormachadogp Nov 26, 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
6 changes: 6 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue}]
charset = utf-8
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
31 changes: 31 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
.DS_Store
dist
dist-ssr
coverage
*.local
.env

/cypress/videos/
/cypress/screenshots/

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

*.tsbuildinfo
7 changes: 7 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

{
"$schema": "https://json.schemastore.org/prettierrc",
"semi": false,
"singleQuote": true,
"printWidth": 100
}
8 changes: 8 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"recommendations": [
"Vue.volar",
"dbaeumer.vscode-eslint",
"EditorConfig.EditorConfig",
"esbenp.prettier-vscode"
]
}
Binary file removed Desktop.png
Binary file not shown.
Binary file removed Mobile.png
Binary file not shown.
227 changes: 121 additions & 106 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,116 +1,131 @@
# Convenia

## Avaliação Técnica - Frontend

> O desafio é muito simples: um SPA responsivo (desktop e mobile) para divisão de gorjeta
> Esperamos avaliar sua melhor implementação para o contexto que estamos propondo.

Que tenha um excelente desenvolvimento :wink:

### Desafio

> Voce deverá desenvolver um SPA ou Aplicação responsiva usando o framework Vue.js e qualquer pacote de componentes que desejar.
> Calculadoras de gorjeta existem aos montes nas principais lojas de aplicativos. Você insere o total da conta, o quanto quer dar de gorjeta e quantas pessoas vão dividir a conta.
> O total da conta pode ser em USD(Dólar) ou EUR(Euro).
> Deve ser exibido a conversão para BRL(R$), obtida via chamada (REST)

Dica: você pode usar qualquer API gratuita para obter a conversão de moedas, como o [SWOP](https://swop.cx/).

### User Story

```gherkin
#language:pt
Funcionalidade: Calculo de Gorjeta
Como Usuário do App
Gostaria de Visualizar
De maneira que estas informações alimentem meu sistema pessoal

Regra: Valores padrão
Dado que não queremos exibição de erros
Então o valor padrão para o campo "Valor" é "0"
E o valor padrão para o campo "Gorjeta" é "10"
E o campo "Gorjeta" pode variar de "10" a "20" %
E o valor padrão para o campo "Pessoas" é "2"
E o campo "Pessoas" pode variar de "2" a "16"

Regra: Exibição
Dado que estejamos entrando no app Le/Tip
E o cliente seja mobile
Então devemos exibir o painel de Entrada

Esquema do Cenário: Cálculo padrão
Dado que estejamos no app Le/Tip
Quando selecionamos EUR no seletor de moeda
E inserirmos <conta> no campo "Valor"
E selecionamos <gorjeta> no campo "Gorjeta"
E selecionamos <pessoas> no campo "Pessoas"
Então visualizamos <conta> em Conta no painel de resultado
E visualizamos <gorjetacalculada> em Gorjeta no painel de resultado
E visualizamos <total> em Total no painel de resultado
E visualizamos <porPessoa> em Por Pessoa no painel de resultado

Exemplo:
|conta|gorjeta|pessoas|gorjetacalculada|total|porPessoa|
|73.23|13 |10 |9.52 |82.75|8.28 |
|60.00|10 |3 |6.00 |66.00|22.00 |
|13.00|15 |2 |1.95 |14.95|7.48 |
|2.58 |17 |3 |0,44 |3.02 |1.01 |

Cenário: Cálculo em reais
Dado que estejamos no app Le/Tip
E selecionamos EUR no seletor de moeda
E inserirmos "13.00" no campo "Valor"
E selecionamos "15" no campo "Gorjeta"
E selecionamos "2" no campo "Pessoas"
Quando o cálculo é realizado de maneira fluente
E o sistema realiza uma chamada de API para obter a conversão para BRL
Então o obtém o resultado da conversão para BRL
E apresenta o valor obtido em "em R$"

Cenário: experiencia mobile
Dado que estejamos no app Le/Tip
E o cliente seja mobile
E estejamos no painel de entrada
Quando pressionarmos o botão ">"
Então o painel de resultado deve ser exibido

Cenário: experiencia mobile, novo cálculo
Dado que estejamos no app Le/Tip
E o cliente seja mobile
E estejamos no painel de resultado
Quando pressionarmos o botão "<"
Então o painel de entrada deve ser exibido

Esquema do Cenário: alteração de moeda
Dado que estejamos no app Le/Tip
Quando alteramos o campo "moeda" para <moeda>
Então todas as etiquetas de moeda devem ser alteradas para <sinal>
E a conversão para BRL deve considerar <moeda>

Exemplo:
|moeda|sinal|
|EUR |€ |
|USD |$ |
# Tip Calculator 💰

> [!IMPORTANT]
>
> Este projeto utiliza uma API externa para buscar as taxas de câmbio. **Para que a funcionalidade de integração com a API funcione corretamente, é necessário adicionar uma API Key no arquivo `src/services/currencyService.js`**.
>
> Para configurar a API Key:
> 1. Obtenha sua API Key na plataforma [SWOP](https://swop.cx/).
> 2. Substitua o valor de `<SUA_API_KEY>` pelo valor da sua chave API.


### Visão Geral
Uma aplicação web de calculadora de gorjetas construída com Vue.js, projetada para ser responsiva e oferecer uma experiência intuitiva para calcular gorjetas e dividir contas.

### Versão Desktop
![image](https://github.com/user-attachments/assets/5b36e1ed-1f93-46e3-aa73-b42668948836)

## Versão Mobile
![image](https://github.com/user-attachments/assets/d5361109-3468-4cf9-865f-448e3d84fb7a)
![image](https://github.com/user-attachments/assets/4f1a0bbb-6066-4f9c-8744-1aa75f310d5c)

### 🚀 Tecnologias Utilizadas

- Vue.js 3 (Composition API)
- Vite
- SASS/SCSS
- Axios (para requisições de API)
- API SWOP

### 🔑 Principais Decisões de Design
#### Arquitetura de Componentes

- Componentização para facilitar manutenção
- Uso de Composition API para lógica de estado
- Separação clara de responsabilidades entre componentes

#### Layout Mobile

- Toggle entre painel de entrada e resultados em telas menores
- Botão flutuante para navegação entre seções
- Design responsivo

#### Conversão de Moeda

- Suporte para USD e EUR
- Conversão em tempo real para BRL
- Tratamento de erros na conversão de moedas

### 🎨 Design no Figma
O design da interface foi criado no Figma, é possivel observar o processo de design até a criação do layout final no link abaixo:

👉 [Design Workflow do Projeto](https://www.figma.com/design/AssQRqrLObmgOIXx5YQIuk/Calculadora-de-Gorjeta-Workflow?node-id=0-1&t=F5VvKkGfJBUx7D7u-1)

### 🔧 Funcionalidades

- Cálculo de gorjeta baseado em percentual
- Divisão de conta entre múltiplas pessoas
- Seleção de moeda (USD/EUR)
- Conversão para BRL
- Layout responsivo
- Botão flutuante para alternar entre o painel de entrada e os resultados em telas menores.

## Configuração Recomendada de IDE

[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (com Vetur desabilitado).

### Instalação e Execução

```sh
npm install
```

### Compilar e Hot-Reload para Desenvolvimento

```sh
npm run dev
```

### Referência visual

#### Desktop
### Linter com [ESLint](https://eslint.org/)

![Mockup Desktop](/Desktop.png)
```sh
npm run lint
```

#### Mobile
### 🧪 Testes
Este projeto possui testes implementados utilizando Vitest e Vue Test Utils para garantir a confiabilidade dos componentes e dos serviços.

![Mockup Desktop](/Mobile.png)
#### Executando os Testes
Para rodar os testes localmente, use o seguinte comando:

### Considerações
```bash
npm run test
```
Isso executará todos os testes definidos na aplicação.

* Como pode perceber, não há um botão "calcular", todos cálculos devem ser reativos
* Apreciamos o uso de alguma metodológia CSS (BEM, RSCSS, ou qualquer outra)
* Avaliaremos como organizará a requisição para conversão de moeda
* A partir do apresentado, você pode incrementar a aplicação como quiser
* Você tem 1(uma) semana para realizar a avaliação

### Aguardamos seu Merge Request
### 🧩 Estrutura do Projeto
```
src/
├── assets/
│ └── base.scss
├── components/
│ ├── AppHeading.vue
│ ├── CurrencyInput.vue
│ ├── CurrencySelector.vue
│ ├── FloatButton.vue
│ ├── RangeInput.vue
│ ├── ResultItem.vue
│ ├── ResultsPanel.vue
│ └── TipCalculator.vue
├── composables/
│ ├── useCurrencyConverter.js
│ └── useExchangeRates.js
├── services/
│ └── currencyService.js
├── tests__/
│ ├── components/
│ │ ├── TipCalculator.spec.vue
│ │ ├── CurrencySelector.spec.vue
│ │ ├── RangeInput.spec.vue
│ │ ├── ResultsPanel.spec.vue
│ │ └── CurrencyInput.spec.vue
│ └── services/
│ ├── currency.integration.spec.js
│ └── currencyService.spec.js
├── App.vue
└── main.js
```


Convenia :purple_heart:
19 changes: 19 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import js from '@eslint/js'
import pluginVue from 'eslint-plugin-vue'
import skipFormatting from '@vue/eslint-config-prettier/skip-formatting'

export default [
{
name: 'app/files-to-lint',
files: ['**/*.{js,mjs,jsx,vue}'],
},

{
name: 'app/files-to-ignore',
ignores: ['**/dist/**', '**/dist-ssr/**', '**/coverage/**'],
},

js.configs.recommended,
...pluginVue.configs['flat/essential'],
skipFormatting,
]
13 changes: 13 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
8 changes: 8 additions & 0 deletions jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
},
"exclude": ["node_modules", "dist"]
}
Loading