Skip to content

Commit 7ea8a00

Browse files
authored
Merge pull request #921 from tusharpamnani/expenseTracker-Tusharpamnani
Expense Tracker
2 parents 9e66179 + 048ff5e commit 7ea8a00

File tree

3 files changed

+328
-0
lines changed

3 files changed

+328
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
7+
<link rel="stylesheet" href="style.css" />
8+
<title>Expense Tracker</title>
9+
</head>
10+
<body>
11+
<h2>Expense Tracker</h2>
12+
13+
<div class="container">
14+
<h4>Your Balance</h4>
15+
<h1 id="balance">$0.00</h1>
16+
17+
<div class="inc-exp-container">
18+
<div>
19+
<h4>Income</h4>
20+
<p id="money-plus" class="money plus">+$0.00</p>
21+
</div>
22+
<div>
23+
<h4>Expense</h4>
24+
<p id="money-minus" class="money minus">-$0.00</p>
25+
</div>
26+
</div>
27+
28+
<h3>History</h3>
29+
<ul id="list" class="list">
30+
<!-- <li class="minus">
31+
Cash <span>-$400</span><button class="delete-btn">x</button>
32+
</li> -->
33+
</ul>
34+
35+
<h3>Add new transaction</h3>
36+
<form id="form">
37+
<div class="form-control">
38+
<label for="text">Text</label>
39+
<input type="text" id="text" placeholder="Enter text..." />
40+
</div>
41+
<div class="form-control">
42+
<label for="amount"
43+
>Amount <br />
44+
(negative - expense, positive - income)</label
45+
>
46+
<input type="number" id="amount" placeholder="Enter amount..." />
47+
</div>
48+
<button class="btn">Add transaction</button>
49+
</form>
50+
</div>
51+
52+
<script src="script.js"></script>
53+
</body>
54+
</html>
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
const balance = document.getElementById('balance');
2+
const money_plus = document.getElementById('money-plus');
3+
const money_minus = 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+
9+
// const dummyTransactions = [
10+
// { id: 1, text: 'Flower', amount: -20 },
11+
// { id: 2, text: 'Salary', amount: 300 },
12+
// { id: 3, text: 'Book', amount: -10 },
13+
// { id: 4, text: 'Camera', amount: 150 }
14+
// ];
15+
16+
const localStorageTransactions = JSON.parse(
17+
localStorage.getItem('transactions')
18+
);
19+
20+
let transactions =
21+
localStorage.getItem('transactions') !== null ? localStorageTransactions : [];
22+
23+
// Add transaction
24+
function addTransaction(e) {
25+
e.preventDefault();
26+
27+
if (text.value.trim() === '' || amount.value.trim() === '') {
28+
alert('Please add a text and amount');
29+
} else {
30+
const transaction = {
31+
id: generateID(),
32+
text: text.value,
33+
amount: +amount.value
34+
};
35+
36+
transactions.push(transaction);
37+
38+
addTransactionDOM(transaction);
39+
40+
updateValues();
41+
42+
updateLocalStorage();
43+
44+
text.value = '';
45+
amount.value = '';
46+
}
47+
}
48+
49+
// Generate random ID
50+
function generateID() {
51+
return Math.floor(Math.random() * 100000000);
52+
}
53+
54+
// Add transactions to DOM list
55+
function addTransactionDOM(transaction) {
56+
// Get sign
57+
const sign = transaction.amount < 0 ? '-' : '+';
58+
59+
const item = document.createElement('li');
60+
61+
// Add class based on value
62+
item.classList.add(transaction.amount < 0 ? 'minus' : 'plus');
63+
64+
item.innerHTML = `
65+
${transaction.text} <span>${sign}${Math.abs(
66+
transaction.amount
67+
)}</span> <button class="delete-btn" onclick="removeTransaction(${
68+
transaction.id
69+
})">x</button>
70+
`;
71+
72+
list.appendChild(item);
73+
}
74+
75+
// Update the balance, income and expense
76+
function updateValues() {
77+
const amounts = transactions.map(transaction => transaction.amount);
78+
79+
const total = amounts.reduce((acc, item) => (acc += item), 0).toFixed(2);
80+
81+
const income = amounts
82+
.filter(item => item > 0)
83+
.reduce((acc, item) => (acc += item), 0)
84+
.toFixed(2);
85+
86+
const expense = (
87+
amounts.filter(item => item < 0).reduce((acc, item) => (acc += item), 0) *
88+
-1
89+
).toFixed(2);
90+
91+
balance.innerText = `$${total}`;
92+
money_plus.innerText = `$${income}`;
93+
money_minus.innerText = `$${expense}`;
94+
}
95+
96+
// Remove transaction by ID
97+
function removeTransaction(id) {
98+
transactions = transactions.filter(transaction => transaction.id !== id);
99+
100+
updateLocalStorage();
101+
102+
init();
103+
}
104+
105+
// Update local storage transactions
106+
function updateLocalStorage() {
107+
localStorage.setItem('transactions', JSON.stringify(transactions));
108+
}
109+
110+
// Init app
111+
function init() {
112+
list.innerHTML = '';
113+
114+
transactions.forEach(addTransactionDOM);
115+
updateValues();
116+
}
117+
118+
init();
119+
120+
form.addEventListener('submit', addTransaction);
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
@import url('https://fonts.googleapis.com/css?family=Lato&display=swap');
2+
3+
:root {
4+
--box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
5+
}
6+
7+
* {
8+
box-sizing: border-box;
9+
}
10+
11+
body {
12+
background-color: #2E4374;
13+
display: flex;
14+
flex-direction: column;
15+
align-items: center;
16+
justify-content: center;
17+
min-height: 100vh;
18+
margin: 0;
19+
font-family: 'Lato', sans-serif;
20+
color: #E5C3A6;
21+
}
22+
23+
.container {
24+
margin: 30px auto;
25+
width: 350px;
26+
}
27+
28+
h1 {
29+
letter-spacing: 1px;
30+
margin: 0;
31+
}
32+
33+
h3 {
34+
border-bottom: 1px solid #bbb;
35+
padding-bottom: 10px;
36+
margin: 40px 0 10px;
37+
}
38+
39+
h4 {
40+
margin: 0;
41+
text-transform: uppercase;
42+
}
43+
44+
.inc-exp-container {
45+
background-color: #4B527E;
46+
box-shadow: var(--box-shadow);
47+
padding: 20px;
48+
display: flex;
49+
justify-content: space-between;
50+
margin: 20px 0;
51+
}
52+
53+
.inc-exp-container > div {
54+
flex: 1;
55+
text-align: center;
56+
}
57+
58+
.inc-exp-container > div:first-of-type {
59+
border-right: 1px solid #4B527E;
60+
}
61+
62+
.money {
63+
font-size: 20px;
64+
letter-spacing: 1px;
65+
margin: 5px 0;
66+
}
67+
68+
.money.plus {
69+
color: #2ecc71;
70+
}
71+
72+
.money.minus {
73+
color: #c0392b;
74+
}
75+
76+
label {
77+
display: inline-block;
78+
margin: 10px 0;
79+
}
80+
81+
input[type='text'],
82+
input[type='number'] {
83+
background-color: #4B527E;
84+
color: #E5C3A6;
85+
border: 1px solid #4B527E;
86+
border-radius: 2px;
87+
display: block;
88+
font-size: 16px;
89+
padding: 10px;
90+
width: 100%;
91+
}
92+
93+
.btn {
94+
cursor: pointer;
95+
background-color: #9c88ff;
96+
box-shadow: var(--box-shadow);
97+
color: #fff;
98+
border: 0;
99+
display: block;
100+
font-size: 16px;
101+
margin: 10px 0 30px;
102+
padding: 10px;
103+
width: 100%;
104+
}
105+
106+
.btn:focus,
107+
.delete-btn:focus {
108+
outline: 0;
109+
}
110+
111+
.list {
112+
list-style-type: none;
113+
padding: 0;
114+
margin-bottom: 40px;
115+
}
116+
117+
.list li {
118+
background-color: #fff;
119+
box-shadow: var(--box-shadow);
120+
color: #333;
121+
display: flex;
122+
justify-content: space-between;
123+
position: relative;
124+
padding: 10px;
125+
margin: 10px 0;
126+
}
127+
128+
.list li.plus {
129+
border-right: 5px solid #2ecc71;
130+
}
131+
132+
.list li.minus {
133+
border-right: 5px solid #c0392b;
134+
}
135+
136+
.delete-btn {
137+
cursor: pointer;
138+
background-color: #e74c3c;
139+
border: 0;
140+
color: #fff;
141+
font-size: 20px;
142+
line-height: 20px;
143+
padding: 2px 5px;
144+
position: absolute;
145+
top: 50%;
146+
left: 0;
147+
transform: translate(-100%, -50%);
148+
opacity: 0;
149+
transition: opacity 0.3s ease;
150+
}
151+
152+
.list li:hover .delete-btn {
153+
opacity: 1;
154+
}

0 commit comments

Comments
 (0)