// ✅ Fetch Transactions from API and Update UI
async function loadTransactions() {
const response = await fetch("/api/transactions");
const transactions = await response.json();
// ✅ Populate Transaction Table
document.getElementById("transactions").innerHTML = transactions
.map(t => `
| $${t.amount} |
${t.date} |
${t.description} |
${t.category} |
|
`).join("");
updateChart(transactions);
updateDashboard(transactions);
loadBudgetChart();
loadSpendingInsights();
loadMonthlyExpensesChart();
}
// ✅ Add Transaction with Validation
async function addTransaction() {
const amount = document.getElementById("amount").value;
const date = document.getElementById("date").value;
const description = document.getElementById("description").value;
const category = document.getElementById("category").value;
// Validation
if (!amount || !date || !description || !category) {
alert("Please fill in all fields!");
return;
}
const data = { amount, date, description, category };
await fetch("/api/transactions", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data)
});
// Clear input fields after submission
document.getElementById("amount").value = "";
document.getElementById("date").value = "";
document.getElementById("description").value = "";
loadTransactions();
}
// ✅ Delete Transaction
async function deleteTransaction(id) {
await fetch(`/api/transactions/${id}`, { method: "DELETE" });
loadTransactions();
}
// ✅ Set Budget for a Category
async function setBudget() {
const category = document.getElementById("budget-category").value;
const amount = document.getElementById("budget-amount").value;
if (!amount) {
alert("Please enter a budget amount!");
return;
}
await fetch("/api/budget", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ category, amount })
});
alert("Budget set successfully!");
loadBudgetChart();
}
// ✅ Load Budget vs Actual Spending Chart
async function loadBudgetChart() {
const transactions = await (await fetch("/api/transactions")).json();
const budgets = await (await fetch("/api/budget")).json();
const actualSpending = {};
const budgetLimits = {};
transactions.forEach(t => {
actualSpending[t.category] = (actualSpending[t.category] || 0) + t.amount;
});
budgets.forEach(b => {
budgetLimits[b.category] = b.amount;
});
const categories = Array.from(new Set([...Object.keys(actualSpending), ...Object.keys(budgetLimits)]));
const actualData = categories.map(cat => actualSpending[cat] || 0);
const budgetData = categories.map(cat => budgetLimits[cat] || 0);
const ctx = document.getElementById('budgetChart').getContext('2d');
if (window.budgetChartInstance) {
window.budgetChartInstance.destroy();
}
window.budgetChartInstance = new Chart(ctx, {
type: 'bar',
data: {
labels: categories,
datasets: [
{ label: "Actual Spending", data: actualData, backgroundColor: "red" },
{ label: "Budget Limit", data: budgetData, backgroundColor: "green" }
]
},
options: {
responsive: true,
scales: {
y: {
beginAtZero: true
}
}
}
});
}
// ✅ Load Monthly Expenses Bar Chart
async function loadMonthlyExpensesChart() {
const transactions = await (await fetch("/api/transactions")).json();
const monthlyTotals = {};
transactions.forEach(t => {
const month = t.date.substring(0, 7);
monthlyTotals[month] = (monthlyTotals[month] || 0) + t.amount;
});
const months = Object.keys(monthlyTotals).sort();
const monthlyData = months.map(month => monthlyTotals[month]);
const ctx = document.getElementById('monthlyExpensesChart').getContext('2d');
if (window.monthlyChartInstance) {
window.monthlyChartInstance.destroy();
}
window.monthlyChartInstance = new Chart(ctx, {
type: 'bar',
data: {
labels: months,
datasets: [
{
label: "Monthly Expenses",
data: monthlyData,
backgroundColor: "#007BFF"
}
]
},
options: {
responsive: true,
scales: {
y: {
beginAtZero: true
}
}
}
});
}
// ✅ Load Spending Insights
async function loadSpendingInsights() {
const response = await fetch("/api/spending-insights");
const insights = await response.json();
let insightsText = "";
for (const [category, message] of Object.entries(insights)) {
insightsText += `${category}: ${message}
`;
}
document.getElementById("spendingInsights").innerHTML = insightsText;
}
// ✅ Update Pie Chart for Category-wise Spending
let expenseChart;
function updateChart(transactions) {
const ctx = document.getElementById('expenseChart').getContext('2d');
const categoryTotals = transactions.reduce((acc, t) => {
acc[t.category] = (acc[t.category] || 0) + t.amount;
return acc;
}, {});
if (expenseChart) {
expenseChart.destroy();
}
expenseChart = new Chart(ctx, {
type: 'pie',
data: {
labels: Object.keys(categoryTotals),
datasets: [{
data: Object.values(categoryTotals),
backgroundColor: ["#FF6384", "#36A2EB", "#FFCE56", "#4CAF50", "#FF9F40", "#9966FF"]
}]
}
});
}
// ✅ Update Dashboard Summary (Total Expenses, Top Category, Recent Transaction)
function updateDashboard(transactions) {
let totalExpenses = transactions.reduce((sum, t) => sum + t.amount, 0);
let categoryTotals = transactions.reduce((acc, t) => {
acc[t.category] = (acc[t.category] || 0) + t.amount;
return acc;
}, {});
let topCategory = Object.keys(categoryTotals).reduce((a, b) => categoryTotals[a] > categoryTotals[b] ? a : b, "None");
let recentTransaction = transactions.length > 0 ? transactions[transactions.length - 1].description : "None";
document.getElementById("totalExpenses").innerText = `$${totalExpenses.toFixed(2)}`;
document.getElementById("topCategory").innerText = topCategory;
document.getElementById("recentTransaction").innerText = recentTransaction;
}
// ✅ Load All Data on Page Load
window.onload = function () {
loadTransactions();
loadBudgetChart();
loadSpendingInsights();
loadMonthlyExpensesChart();
};