Skip to content
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
26 changes: 26 additions & 0 deletions Expense-Tracker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Expense Tracker

## 📚 Technologies Used 📚

- **JavaScript**: The primary language used for creating this project.
- **HTML**: Used to structure the content on the webpage.
- **CSS**: Used for styling the webpage.

## 🎯 Purpose of this Project 🎯

The main goal of this project is to demonstrate the use of JavaScript for creating a simple expense tracker application. It showcases the use of JavaScript DOM manipulation, event handling, and local storage.

## 📂 Project Structure 📂

This project is contained in its own directory. Here is a brief overview of the project structure:

- `index.html`: This file contains the HTML structure of the project.
- `script.js`: This file contains the JavaScript code for the project.
- `style.css`: This file contains the CSS styles for the project.

## 🚀 How to Run this Project 🚀

1. Clone the repository and navigate to the Expense Tracker directory.
2. Open `index.html` in your browser.
3. Start adding expenses and see the total balance update dynamically.
4. Your expenses will be saved in the local storage, so you can revisit the page and see your previous expenses.
37 changes: 37 additions & 0 deletions Expense-Tracker/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Expense Tracker</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="expense-tracker">
<div class="expense-header">
<h2>Expense Tracker</h2>
<button class="add-expense-btn">Add Expense</button>
</div>
<input type="text" id="search" placeholder="Search expenses...">
<div class="expense-list"></div>
<div class="total-expenses">
<h3>Total Expense: $0</h3>
</div>
</div>

<!-- Modal for adding expense -->
<div id="expense-modal" class="modal">
<div class="modal-content">
<span class="close-btn">&times;</span>
<h2>Add New Expense</h2>
<input type="text" id="expense-description" placeholder="Description">
<input type="number" id="expense-amount" placeholder="Amount">
<input type="date" id="expense-date">
<button id="save-expense-btn">Save</button>
</div>
</div>

<script src="script.js"></script>
</body>
</html>
98 changes: 98 additions & 0 deletions Expense-Tracker/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
const addExpenseBtn = document.querySelector(".add-expense-btn");
const expenseList = document.querySelector(".expense-list");
const totalExpenses = document.querySelector(".total-expenses h3");
const modal = document.getElementById("expense-modal");
const closeModalBtn = document.querySelector(".close-btn");
const saveExpenseBtn = document.getElementById("save-expense-btn");
const searchInput = document.getElementById("search");

let expenses = JSON.parse(localStorage.getItem('expenses')) || [];
let total = 0;

function updateTotal() {
total = expenses.reduce((acc, expense) => acc + expense.amount, 0);
}

function renderExpenses() {
let html = "";
expenses.forEach((expense, index) => {
html += `
<div class="expense-item" data-index="${index}">
<div class="expense-item-description">${expense.description}</div>
<div class="expense-item-amount">$${expense.amount.toFixed(2)}</div>
<div>${new Date(expense.date).toLocaleDateString()}</div>
<button class="delete-expense-btn">&times;</button>
</div>
`;
});
expenseList.innerHTML = html;
totalExpenses.innerText = `Total Expenses: $${total.toFixed(2)}`;
}

function addExpense() {
const description = document.getElementById("expense-description").value;
const amount = parseFloat(document.getElementById("expense-amount").value);
const date = document.getElementById("expense-date").value;

if (description && amount && date) {
const expense = { description, amount, date };
expenses.push(expense);
localStorage.setItem('expenses', JSON.stringify(expenses));
updateTotal();
renderExpenses();
closeModal();
}
}

function deleteExpense(index) {
expenses.splice(index, 1);
localStorage.setItem('expenses', JSON.stringify(expenses));
updateTotal();
renderExpenses();
}

function openModal() {
modal.style.display = "block";
}

function closeModal() {
modal.style.display = "none";
document.getElementById("expense-description").value = '';
document.getElementById("expense-amount").value = '';
document.getElementById("expense-date").value = '';
}

function filterExpenses() {
const searchTerm = searchInput.value.toLowerCase();
document.querySelectorAll(".expense-item").forEach(item => {
const description = item.querySelector(".expense-item-description").textContent.toLowerCase();
if (description.includes(searchTerm)) {
item.style.display = "";
} else {
item.style.display = "none";
}
});
}

addExpenseBtn.addEventListener("click", openModal);
closeModalBtn.addEventListener("click", closeModal);
saveExpenseBtn.addEventListener("click", addExpense);

expenseList.addEventListener("click", function(event) {
if (event.target.classList.contains("delete-expense-btn")) {
const index = event.target.parentElement.getAttribute("data-index");
deleteExpense(index);
}
});

window.addEventListener("click", function(event) {
if (event.target == modal) {
closeModal();
}
});

searchInput.addEventListener("input", filterExpenses);

// Initial render
updateTotal();
renderExpenses();
162 changes: 162 additions & 0 deletions Expense-Tracker/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
body {
background-color: #f2f2f2;
font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;
}

.expense-tracker {
max-width: 500px;
margin: 0 auto;
padding: 20px;
border: 1px solid #ccc;
border-radius: 5px;
background-color: #fff;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
box-sizing: border-box;
/* Ensure padding and border are included in total width */
}

.expense-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}

.add-expense-btn {
padding: 10px 30px;
background-color: #4caf50;
color: #fff;
border: none;
font-size: 16px;
font-weight: 600;
text-transform: uppercase;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s ease;
}

.add-expense-btn:hover {
background-color: #45a049;
}

.total-expenses {
text-align: right;
font-size: 1.2em;
font-weight: bold;
}

.expense-list {
margin-bottom: 20px;
}

.expense-item {
display: flex;
justify-content: space-between;
align-items: center;
background-color: #f9f9f9;
padding: 10px;
border-radius: 5px;
margin-bottom: 10px;
transition: transform 0.3s ease;
}

.expense-item:hover {
transform: scale(1.05);
}

.expense-item-description {
font-weight: bold;
}

.expense-item-amount {
font-weight: bold;
}

.delete-expense-btn {
background-color: #f44336;
color: #fff;
border: none;
border-radius: 50%;
width: 30px;
height: 30px;
font-size: 16px;
font-weight: bold;
cursor: pointer;
}

#search {
width: calc(100% - 22px);
/* Ensure search input fits within the container */
padding: 10px;
margin-bottom: 20px;
border: 1px solid #ccc;
border-radius: 5px;
box-sizing: border-box;
/* Ensure padding and border are included in total width */
}

.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.4);
}

.modal-content {
background-color: #fff;
margin: 15% auto;
padding: 20px;
border: 1px solid #ccc;
border-radius: 5px;
width: 80%;
max-width: 400px;
box-sizing: border-box;
/* Ensure padding and border are included in total width */
}

.close-btn {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
cursor: pointer;
}

.close-btn:hover,
.close-btn:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}

#expense-description,
#expense-amount,
#expense-date {
width: calc(100% - 22px);
/* Ensure input fields fit within the modal */
padding: 10px;
margin: 10px 0;
border: 1px solid #ccc;
border-radius: 5px;
box-sizing: border-box;
/* Ensure padding and border are included in total width */
}

#save-expense-btn {
padding: 10px 20px;
background-color: #4caf50;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
}

#save-expense-btn:hover {
background-color: #45a049;
}