diff --git a/Expense-Tracker/README.md b/Expense-Tracker/README.md new file mode 100644 index 0000000..0d3ffed --- /dev/null +++ b/Expense-Tracker/README.md @@ -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. \ No newline at end of file diff --git a/Expense-Tracker/index.html b/Expense-Tracker/index.html new file mode 100644 index 0000000..bbfe9b9 --- /dev/null +++ b/Expense-Tracker/index.html @@ -0,0 +1,37 @@ + + + + + + + Expense Tracker + + + +
+
+

Expense Tracker

+ +
+ +
+
+

Total Expense: $0

+
+
+ + + + + + + diff --git a/Expense-Tracker/script.js b/Expense-Tracker/script.js new file mode 100644 index 0000000..76f263f --- /dev/null +++ b/Expense-Tracker/script.js @@ -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 += ` +
+
${expense.description}
+
$${expense.amount.toFixed(2)}
+
${new Date(expense.date).toLocaleDateString()}
+ +
+ `; + }); + 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(); diff --git a/Expense-Tracker/style.css b/Expense-Tracker/style.css new file mode 100644 index 0000000..717f69e --- /dev/null +++ b/Expense-Tracker/style.css @@ -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; +} \ No newline at end of file