Skip to content

Commit 2d4a4fb

Browse files
committed
add expense tracker
1 parent cf86df2 commit 2d4a4fb

File tree

4 files changed

+139
-16
lines changed

4 files changed

+139
-16
lines changed

67-expense tracker/index.html

+5-10
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,7 @@ <h4>Expense</h4>
2828
</div>
2929
</div>
3030
<h3>History</h3>
31-
<ul id="list" class="list">
32-
<!-- <li class="minus">
33-
Cash <span>-$400</span
34-
><button class="delete-btn"><i class="fa fa-times"></i></button>
35-
</li>
36-
<li class="plus">
37-
Cash <span>$400</span
38-
><button class="delete-btn"><i class="fa fa-times"></i></button>
39-
</li> -->
40-
</ul>
31+
<ul id="list" class="list"></ul>
4132
<h3>Add new transaction</h3>
4233
<form id="form">
4334
<div class="form-control">
@@ -54,6 +45,10 @@ <h3>Add new transaction</h3>
5445
<button class="btn">Add transaction</button>
5546
</form>
5647
</div>
48+
<!-- Notification -->
49+
<div class="notification-container" id="notification">
50+
<p>Please add a description and amount</p>
51+
</div>
5752
<script src="script.js"></script>
5853
</body>
5954
</html>

67-expense tracker/script.js

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
const balance = document.getElementById("balance");
2+
const moneyPlus = document.getElementById("money-plus");
3+
const moneyMinus = document.getElementById("money-minus");
4+
const list = document.getElementById("list");
5+
const form = document.getElementById("form");
6+
const text = document.getElementById("text");
7+
const amount = document.getElementById("amount");
8+
const notification = document.getElementById("notification");
9+
10+
// const dummyTransactions = [
11+
// { id: 1, text: "Flower", amount: -20 },
12+
// { id: 2, text: "Salary", amount: 300 },
13+
// { id: 3, text: "Book", amount: -10 },
14+
// { id: 4, text: "Camera", amount: 150 },
15+
// ];
16+
17+
// let transactions = dummyTransactions;
18+
19+
const localStorageTransactions = JSON.parse(
20+
localStorage.getItem("transactions")
21+
);
22+
let transactions =
23+
localStorageTransactions !== null ? localStorageTransactions : [];
24+
25+
function updateLocaleStorage() {
26+
localStorage.setItem("transactions", JSON.stringify(transactions));
27+
}
28+
29+
function showNotification() {
30+
notification.classList.add("show");
31+
setTimeout(() => {
32+
notification.classList.remove("show");
33+
}, 2000);
34+
}
35+
36+
function generateID() {
37+
return Math.floor(Math.random() * 100000000);
38+
}
39+
40+
function addTransaction(e) {
41+
e.preventDefault();
42+
if (text.value.trim() === "" || amount.value.trim() === "") {
43+
showNotification();
44+
} else {
45+
const transaction = {
46+
id: generateID(),
47+
text: text.value,
48+
amount: +amount.value,
49+
};
50+
transactions.push(transaction);
51+
addTransactionDOM(transaction);
52+
updateValues();
53+
updateLocaleStorage();
54+
text.value = "";
55+
amount.value = "";
56+
}
57+
}
58+
59+
function addTransactionDOM(transaction) {
60+
const sign = transaction.amount < 0 ? "-" : "+";
61+
const item = document.createElement("li");
62+
item.classList.add(sign === "+" ? "plus" : "minus");
63+
item.innerHTML = `
64+
${transaction.text} <span>${sign}${Math.abs(transaction.amount)}</span
65+
><button class="delete-btn" onclick="removeTransaction(${
66+
transaction.id
67+
})"><i class="fa fa-times"></i></button>
68+
`;
69+
list.appendChild(item);
70+
}
71+
72+
function updateValues() {
73+
const amounts = transactions.map((transaction) => transaction.amount);
74+
const total = amounts
75+
.reduce((accumulator, value) => (accumulator += value), 0)
76+
.toFixed(2);
77+
const income = amounts
78+
.filter((value) => value > 0)
79+
.reduce((accumulator, value) => (accumulator += value), 0)
80+
.toFixed(2);
81+
const expense = (
82+
amounts
83+
.filter((value) => value < 0)
84+
.reduce((accumulator, value) => (accumulator += value), 0) * -1
85+
).toFixed(2);
86+
balance.innerText = `$${total}`;
87+
moneyPlus.innerText = `$${income}`;
88+
moneyMinus.innerText = `$${expense}`;
89+
}
90+
91+
function removeTransaction(id) {
92+
transactions = transactions.filter((transaction) => transaction.id !== id);
93+
updateLocaleStorage();
94+
init();
95+
}
96+
97+
// Init
98+
function init() {
99+
list.innerHTML = "";
100+
transactions.forEach(addTransactionDOM);
101+
updateValues();
102+
}
103+
104+
init();
105+
106+
form.addEventListener("submit", addTransaction);

67-expense tracker/style.css

+27-5
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,8 @@ input[type="number"] {
137137
position: relative;
138138
padding: 10px;
139139
margin: 10px 0;
140-
border-radius: 5px;
140+
border-top-left-radius: 5px;
141+
border-bottom-left-radius: 5px;
141142
}
142143

143144
.list li.plus {
@@ -152,14 +153,16 @@ input[type="number"] {
152153
cursor: pointer;
153154
background-color: var(--minus-color);
154155
color: var(--background-secondary-color);
156+
box-shadow: var(--box-shadow);
155157
border: 0;
156-
font-size: 20px;
157-
line-height: 20px;
158-
padding: 2px 5px;
158+
font-size: 22px;
159+
line-height: 22px;
160+
padding: 10px;
161+
margin: 10px 0;
159162
position: absolute;
160163
top: 50%;
161164
right: 0;
162-
transform: translate(105%, -50%);
165+
transform: translate(100%, -73%);
163166
opacity: 0;
164167
transition: opacity 0.3s ease;
165168
}
@@ -172,3 +175,22 @@ input[type="number"] {
172175
.list li:hover .delete-btn {
173176
opacity: 1;
174177
}
178+
179+
.notification-container {
180+
background-color: var(--minus-color);
181+
color: var(--background-secondary-color);
182+
border-radius: 5px 5px 0 0;
183+
padding: 15px 20px;
184+
position: fixed;
185+
bottom: 0;
186+
opacity: 0;
187+
transition: opacity 0.3s ease;
188+
}
189+
190+
.notification-container.show {
191+
opacity: 1;
192+
}
193+
194+
.notification-container p {
195+
margin: 0;
196+
}

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
| 64 | [Menu Slider & Modal](https://github.com/solygambas/html-css-fifty-projects/tree/master/64-menu%20slider%20modal) | [Live Demo](https://codepen.io/solygambas/full/MWbLeKd) |
7373
| 65 | [Hangman Game](https://github.com/solygambas/html-css-fifty-projects/tree/master/65-hangman%20game) | [Live Demo](https://codepen.io/solygambas/full/MWbLEYr) |
7474
| 66 | [Meal Finder](https://github.com/solygambas/html-css-fifty-projects/tree/master/66-meal%20finder) | [Live Demo](https://codepen.io/solygambas/full/dyOagYE) |
75-
| 67 | [Expense Tracker](https://github.com/solygambas/html-css-fifty-projects/tree/master/67-expense%20tracker) | [Live Demo](#) |
75+
| 67 | [Expense Tracker](https://github.com/solygambas/html-css-fifty-projects/tree/master/67-expense%20tracker) | [Live Demo](https://codepen.io/solygambas/full/OJbqyro) |
7676

7777
Mainly based on 2 courses by Brad Traversy (2020):
7878

0 commit comments

Comments
 (0)