35200-vm/assets/js/main.js
2025-10-24 15:51:10 +00:00

150 lines
6.4 KiB
JavaScript

document.addEventListener('DOMContentLoaded', () => {
const initialBalanceEl = document.getElementById('initialBalance');
const currentBalanceEl = document.getElementById('currentBalance');
const transactionHistoryEl = document.getElementById('transactionHistory');
const incomeForm = document.getElementById('incomeForm');
const expenseForm = document.getElementById('expenseForm');
const incomeModal = new bootstrap.Modal(document.getElementById('incomeModal'));
const expenseModal = new bootstrap.Modal(document.getElementById('expenseModal'));
const toastEl = document.getElementById('liveToast');
const toast = new bootstrap.Toast(toastEl);
// Search elements
const startDateEl = document.getElementById('startDate');
const endDateEl = document.getElementById('endDate');
const searchBtn = document.getElementById('searchBtn');
const clearBtn = document.getElementById('clearBtn');
let transactions = JSON.parse(localStorage.getItem('transactions')) || [];
let initialBalance = parseFloat(localStorage.getItem('initialBalance')) || 0;
initialBalanceEl.value = initialBalance;
const formatCurrency = (amount) => {
return new Intl.NumberFormat('en-IN', { style: 'currency', currency: 'INR' }).format(amount);
};
const showToast = (message, type) => {
const toastBody = toastEl.querySelector('.toast-body');
const toastHeader = toastEl.querySelector('.toast-header');
toastBody.textContent = message;
toastHeader.classList.remove('bg-success', 'bg-danger');
toastHeader.classList.add(type === 'success' ? 'bg-success' : 'bg-danger');
toast.show();
};
const renderTransactions = (transactionsToRender) => {
transactionHistoryEl.innerHTML = '';
let balance = initialBalance;
transactions.forEach(t => balance += t.amount);
if (transactionsToRender.length === 0) {
transactionHistoryEl.innerHTML = '<tr><td colspan="5" class="text-center text-muted">No transactions found for this period.</td></tr>';
} else {
transactionsToRender.slice().reverse().forEach(transaction => {
const row = document.createElement('tr');
const typeClass = transaction.amount > 0 ? 'text-success' : 'text-danger';
row.innerHTML = `
<td>${new Date(transaction.date).toLocaleDateString()}</td>
<td><span class="badge bg-${transaction.amount > 0 ? 'success' : 'danger'}">${transaction.amount > 0 ? 'Income' : 'Expense'}</span></td>
<td>${transaction.description}</td>
<td class="text-end fw-bold ${typeClass}">${formatCurrency(transaction.amount)}</td>
<td><button class="btn btn-sm btn-outline-danger delete-btn" data-id="${transaction.id}"><i class="bi bi-trash"></i></button></td>
`;
transactionHistoryEl.appendChild(row);
});
}
currentBalanceEl.textContent = formatCurrency(balance);
};
const addTransaction = (amount, description, date) => {
const transaction = {
id: Date.now(),
date: date || new Date().toISOString().split('T')[0],
amount: amount,
description: description
};
transactions.push(transaction);
localStorage.setItem('transactions', JSON.stringify(transactions));
renderTransactions(transactions);
};
const deleteTransaction = (id) => {
transactions = transactions.filter(t => t.id !== id);
localStorage.setItem('transactions', JSON.stringify(transactions));
renderTransactions(transactions);
showToast('Transaction deleted successfully!', 'success');
};
transactionHistoryEl.addEventListener('click', (e) => {
if (e.target.closest('.delete-btn')) {
const id = parseInt(e.target.closest('.delete-btn').dataset.id);
deleteTransaction(id);
}
});
initialBalanceEl.addEventListener('input', (e) => {
initialBalance = parseFloat(e.target.value) || 0;
localStorage.setItem('initialBalance', initialBalance);
renderTransactions(transactions);
});
incomeForm.addEventListener('submit', (e) => {
e.preventDefault();
const amount = parseFloat(document.getElementById('incomeAmount').value);
const description = document.getElementById('incomeDescription').value;
const date = document.getElementById('incomeDate').value;
if (amount > 0 && description && date) {
addTransaction(amount, description, date);
showToast('Income added successfully!', 'success');
incomeForm.reset();
document.getElementById('incomeDate').valueAsDate = new Date();
incomeModal.hide();
} else {
showToast('Please enter a valid amount, description, and date.', 'danger');
}
});
expenseForm.addEventListener('submit', (e) => {
e.preventDefault();
const amount = parseFloat(document.getElementById('expenseAmount').value);
const description = document.getElementById('expenseDescription').value;
const date = document.getElementById('expenseDate').value;
if (amount > 0 && description && date) {
addTransaction(-amount, description, date);
showToast('Expense added successfully!', 'success');
expenseForm.reset();
document.getElementById('expenseDate').valueAsDate = new Date();
expenseModal.hide();
} else {
showToast('Please enter a valid amount, description, and date.', 'danger');
}
});
searchBtn.addEventListener('click', () => {
const startDate = startDateEl.value;
const endDate = endDateEl.value;
if (!startDate || !endDate) {
showToast('Please select both a start and end date.', 'danger');
return;
}
const filteredTransactions = transactions.filter(t => {
const transactionDate = t.date;
return transactionDate >= startDate && transactionDate <= endDate;
});
renderTransactions(filteredTransactions);
});
clearBtn.addEventListener('click', () => {
startDateEl.value = '';
endDateEl.value = '';
renderTransactions(transactions);
});
renderTransactions(transactions);
});