Skip to content

Commit 2791bdd

Browse files
✨ features implemented & minors fix
1 parent 57e4b07 commit 2791bdd

11 files changed

+239
-56
lines changed

README.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,11 @@
2121
Aplicação de controle de financeiro, desenvolvida durante a Maratona Discover realizada pela <a href="https://github.com/Rocketseat">@Rocketseat</a>
2222

2323
## Features:
24-
- [ ] Cadastro de novas trasações<br>
25-
- [ ] Exclusão de trasações<br>
26-
- [ ] Valor total de entrada de trasações<br>
27-
- [ ] Valor total de saída de trasações<br>
28-
- [ ] Valor total disponível<br>
29-
- [x] Modal<br>
24+
- [x] Cadastro de novas trasações com descrição, valor e data<br>
25+
- [x] Valor total atualizado do saldo de entradas/saídas das trasações<br>
26+
- [x] Valor total atualizado do saldo atual<br>
27+
- [x] Exclusão de transações, atualizando os saldos (entradas, saídas e saldo atual)<br>
28+
- [x] Modal para cadastro de novas transações<br>
3029
- [x] Responsividade<br>
3130

3231
# Techs:
6 KB
Loading
18.3 KB
Loading

assets/favicon/apple-touch-icon.png

5.3 KB
Loading

assets/favicon/favicon-16x16.png

364 Bytes
Loading

assets/favicon/favicon-32x32.png

772 Bytes
Loading

assets/favicon/favicon.ico

15 KB
Binary file not shown.

index.html

Lines changed: 30 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,32 @@
11
<!DOCTYPE html>
2-
<html lang="pt-br">
2+
<html lang="pt-BR">
33

4-
<head>
4+
<head prefix="og: http://ogp.me/ns#">
55
<meta charset="UTF-8">
66
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7-
<link rel="stylesheet" href="style.css">
7+
<title>dev.finance$</title>
8+
<!-- FONT & STYLE -->
89
<link rel="preconnect" href="https://fonts.gstatic.com">
910
<link
1011
href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,400;0,700;1,100;1,400;1,700&display=swap"
1112
rel="stylesheet">
12-
<title>dev.finance$</title>
13+
<link rel="stylesheet" href="./style.css">
14+
<!-- META NAME & DESCRIPTION -->
15+
<meta name="author" content="Cleilson Andrade">
16+
<meta name="description" content="Seu app de controle de finanças pessoal.">
17+
<!-- META SOCIAL MEDIAS -->
18+
<meta name="twitter:title" content="dev.finance$">
19+
<meta property="og:title" content="dev.finance$" />
20+
<meta property="og:image" content="./design/desktop.png" />
21+
<meta property="og:description" content="Seu app de controle de finanças pessoal." />
22+
<meta property="og:site_name" content="dev.finance$" />
23+
<meta property="og:locale" content="pt_BR" />
24+
<!-- FAVICONS -->
25+
<link rel="apple-touch-icon" sizes="180x180" href="./assets/favicon/apple-touch-icon.png">
26+
<link rel="icon" type="image/png" sizes="32x32" href="./assets/favicon/favicon-32x32.png">
27+
<link rel="icon" type="image/png" sizes="16x16" href="./assets/favicon/favicon-16x16.png">
28+
<link rel="shortcut icon" href="./assets/favicon/favicon.ico" type="image/x-icon">
29+
<link rel="manifest" href="./site.webmanifest">
1330
</head>
1431

1532
<body>
@@ -27,7 +44,7 @@ <h3>
2744
</span>
2845
<img src="./assets/income.svg" alt="Imagem de entradas">
2946
</h3>
30-
<p>R$ 5.000,00</p>
47+
<p id="incomeDisplay">R$ 0,00</p>
3148
</div>
3249
<div class="card">
3350
<h3>
@@ -36,7 +53,7 @@ <h3>
3653
</span>
3754
<img src="./assets/expense.svg" alt="Imagem de saídas">
3855
</h3>
39-
<p>R$ 5.000,00</p>
56+
<p id="expenseDisplay">R$ 0,00</p>
4057
</div>
4158
<div class="card total">
4259
<h3>
@@ -45,7 +62,7 @@ <h3>
4562
</span>
4663
<img src="./assets/total.svg" alt="Imagem de total">
4764
</h3>
48-
<p>R$ 3.000,00</p>
65+
<p id="totalDisplay">R$ 0,00</p>
4966
</div>
5067
</section>
5168

@@ -62,30 +79,6 @@ <h2 class="sr-only">Transações</h2>
6279
</tr>
6380
</thead>
6481
<tbody>
65-
<tr>
66-
<td>Luz</td>
67-
<td>- R$ 500,00</td>
68-
<td>23/01/2021</td>
69-
<td>
70-
<img src="./assets/minus.svg" alt="Remover transação">
71-
</td>
72-
</tr>
73-
<tr>
74-
<td>Criação website</td>
75-
<td>R$ 5000,00</td>
76-
<td>23/01/2021</td>
77-
<td>
78-
<img src="./assets/minus.svg" alt="Remover transação">
79-
</td>
80-
</tr>
81-
<tr>
82-
<td>Internet</td>
83-
<td>-R$ 200,00</td>
84-
<td>23/01/2021</td>
85-
<td>
86-
<img src="./assets/minus.svg" alt="Remover transação">
87-
</td>
88-
</tr>
8982
</tbody>
9083
</table>
9184
</section>
@@ -95,25 +88,25 @@ <h2 class="sr-only">Transações</h2>
9588
<div class="modal">
9689
<div id="form">
9790
<h2>Nova Transação</h2>
98-
<form action="">
91+
<form action="" onsubmit="Form.submit(event)">
9992
<div class="input-group">
10093
<label class="sr-only" for="description">
10194
Descrição
10295
</label>
10396
<input type="text" id="description" name="description" placeholder="Descrição">
10497
</div>
10598
<div class="input-group">
106-
<label class="sr-only" for="amout">Valor</label>
107-
<input type="number" step="0.01" id="amout" name="amount" placeholder="0,00">
108-
<small class="help">Use o sinal " - " (negativo) para despesas e " , " (vírgula) para casas
99+
<label class="sr-only" for="amount">Valor</label>
100+
<input type="number" step="0.01" id="amount" name="amount" placeholder="0,00">
101+
<small>Use o sinal " - " (negativo) para despesas e " , " (vírgula) para casas
109102
decimais</small>
110103
</div>
111104
<div class="input-group">
112105
<label class="sr-only" for="date">Data</label>
113106
<input type="date" id="date" name="date">
114107
</div>
115108
<div class="input-group actions">
116-
<a ondblclick="Modal.close()" href="#" class="button cancel">Cancelar</a>
109+
<a onclick="Modal.close()" href="#" class="button cancel">Cancelar</a>
117110
<button>Salvar</button>
118111
</div>
119112
</form>
@@ -123,19 +116,7 @@ <h2>Nova Transação</h2>
123116

124117
<footer>dev.finance$</footer>
125118

126-
<script>
127-
const Modal = {
128-
open() {
129-
// ABRIR MODAL
130-
// Adicionar a class active ao modal
131-
document.querySelector('.modal-overlary').classList.add('active')
132-
},
133-
close() {
134-
// FECHAR MODAL
135-
// Remover a class active do modal
136-
document.querySelector('.modal-overlay').classList.remove('active')
137-
}
138-
}
119+
<script src="./scripts.js">
139120
</script>
140121
</body>
141122

scripts.js

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
const Modal = {
2+
open() {
3+
// ABRIR MODAL
4+
// Adicionar a class active ao modal
5+
document.querySelector('.modal-overlay').classList.add('active')
6+
},
7+
close() {
8+
// FECHAR MODAL
9+
// Remover a class active do modal
10+
document.querySelector('.modal-overlay').classList.remove('active')
11+
},
12+
}
13+
14+
const Storage = {
15+
get() {
16+
return JSON.parse(localStorage.getItem("dev.finances:transactions")) || []
17+
},
18+
set(transactions) {
19+
localStorage.setItem("dev.finances:transactions", JSON.stringify(transactions))
20+
}
21+
}
22+
23+
const Transaction = {
24+
all: Storage.get(),
25+
add(transaction) {
26+
Transaction.all.push(transaction)
27+
28+
App.reload()
29+
},
30+
remove(index) {
31+
Transaction.all.splice(index, 1)
32+
33+
App.reload()
34+
},
35+
incomes() {
36+
let income = 0
37+
Transaction.all.forEach(transaction => {
38+
if (transaction.amount > 0) {
39+
income += transaction.amount
40+
}
41+
})
42+
return income
43+
},
44+
expenses() {
45+
let expense = 0
46+
Transaction.all.forEach(transaction => {
47+
if (transaction.amount < 0) {
48+
expense += transaction.amount
49+
}
50+
})
51+
return expense
52+
},
53+
total() {
54+
return Transaction.incomes() + Transaction.expenses()
55+
},
56+
}
57+
58+
const DOM = {
59+
transactionsContainer: document.querySelector('#data-table tbody'),
60+
addTransaction(transaction, index) {
61+
const tr = document.createElement('tr')
62+
tr.innerHTML = DOM.innerHTMLTransaction(transaction, index)
63+
tr.dataset.index = index
64+
DOM.transactionsContainer.appendChild(tr)
65+
},
66+
innerHTMLTransaction(transaction, index) {
67+
const CSSclass = transaction.amount > 0 ? "income" : "expense"
68+
const amount = Utils.formatCurrency(transaction.amount)
69+
const html = `
70+
<td class="description">${transaction.description}</td>
71+
<td class="${CSSclass}">${amount}</td>
72+
<td class="date">${transaction.date}</td>
73+
<td>
74+
<img onclick="Transaction.remove(${index})" src="./assets/minus.svg" alt="Remover transação">
75+
</td>
76+
`
77+
return html
78+
},
79+
updateBalance() {
80+
document.getElementById('incomeDisplay').innerHTML = Utils.formatCurrency(Transaction.incomes())
81+
document.getElementById('expenseDisplay').innerHTML = Utils.formatCurrency(Transaction.expenses())
82+
document.getElementById('totalDisplay').innerHTML = Utils.formatCurrency(Transaction.total())
83+
},
84+
clearTransactions() {
85+
DOM.transactionsContainer.innerHTML = ""
86+
}
87+
}
88+
89+
const Utils = {
90+
formatDate(date) {
91+
const splittedDate = date.split("-")
92+
return `${splittedDate[2]}/${splittedDate[1]}/${splittedDate[0]}`
93+
},
94+
formartAmount(value) {
95+
value = Number(value.replace(/\,\./g, "")) * 100
96+
97+
return value
98+
},
99+
formatCurrency(value) {
100+
const signal = Number(value) < 0 ? "-" : ""
101+
value = String(value).replace(/\D/g, "")
102+
value = Number(value) / 100
103+
value = value.toLocaleString("pt-BR", {
104+
style: "currency",
105+
currency: "BRL"
106+
})
107+
108+
return signal + value
109+
},
110+
}
111+
112+
const Form = {
113+
description: document.querySelector('input#description'),
114+
amount: document.querySelector('input#amount'),
115+
date: document.querySelector('input#date'),
116+
getValues() {
117+
return {
118+
description: Form.description.value,
119+
amount: Form.amount.value,
120+
date: Form.date.value
121+
}
122+
},
123+
124+
validateFields() {
125+
const { description, amount, date } = Form.getValues()
126+
127+
if (description.trim() === "" || amount.trim() === "" || date.trim() === "") {
128+
throw new Error("Por favor, preencha todos os campos!")
129+
}
130+
},
131+
132+
formatValues() {
133+
let { description, amount, date } = Form.getValues()
134+
135+
amount = Utils.formartAmount(amount)
136+
137+
date = Utils.formatDate(date)
138+
139+
return {
140+
description,
141+
amount,
142+
date,
143+
}
144+
},
145+
146+
clearFields() {
147+
Form.description.value = ""
148+
Form.amount.value = ""
149+
Form.date.value = ""
150+
},
151+
152+
submit(event) {
153+
event.preventDefault()
154+
155+
try {
156+
Form.validateFields()
157+
const transaction = Form.formatValues()
158+
Transaction.add(transaction)
159+
Form.clearFields()
160+
Modal.close()
161+
} catch (error) {
162+
alert(error.message)
163+
}
164+
165+
},
166+
}
167+
168+
const App = {
169+
init() {
170+
Transaction.all.forEach(DOM.addTransaction)
171+
DOM.updateBalance()
172+
Storage.set(Transaction.all)
173+
},
174+
reload() {
175+
DOM.clearTransactions()
176+
App.init()
177+
},
178+
}
179+
180+
App.init()

site.webmanifest

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "dev.finance$",
3+
"short_name": "dev.finance$",
4+
"lang": "pt-BR",
5+
"description": "Seu app de controle de finanças pessoal.",
6+
"icons": [
7+
{
8+
"src": "./assets/favicon/android-chrome-192x192.png",
9+
"sizes": "192x192",
10+
"type": "image/png"
11+
},
12+
{
13+
"src": "./assets/favicon/android-chrome-512x512.png",
14+
"sizes": "512x512",
15+
"type": "image/png"
16+
}
17+
],
18+
"theme_color": "#ffffff",
19+
"background_color": "#f0f2f5",
20+
"display": "standalone"
21+
}

style.css

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ a {
5454
}
5555

5656
a:hover {
57+
transition: 0.2s;
5758
color: var(--light-green);
5859
}
5960

@@ -124,7 +125,7 @@ header {
124125
}
125126

126127
.card:hover {
127-
transition: 0.2s;
128+
transition: 0.4s;
128129
background: #e8f0ff;
129130
}
130131

@@ -216,6 +217,7 @@ td.expense {
216217
opacity: 0;
217218
visibility: hidden;
218219
z-index: 999;
220+
transition: 0.2s;
219221
}
220222

221223
.modal-overlay.active {

0 commit comments

Comments
 (0)