diff --git a/mft/static/app.js b/mft/static/app.js index 8e950ec..24e2964 100644 --- a/mft/static/app.js +++ b/mft/static/app.js @@ -1,5 +1,8 @@ const TOKEN_KEY = 'mft_token'; +// Store categories for mapping cid to name +let categories = []; + // Validate token with the API async function validateToken(token) { try { @@ -95,7 +98,8 @@ document.getElementById('expense-form').addEventListener('submit', async (e) => // Reset form document.getElementById('expense-form').reset(); - // TODO: Update local expense view with the new expense + // Add to expense list + addExpenseToList(expense); } catch (error) { console.error('Error adding expense:', error); alert(`Failed to add expense: ${error.message}`); @@ -111,6 +115,7 @@ async function showApp() { document.getElementById('login-section').style.display = 'none'; document.getElementById('app-section').style.display = 'block'; await loadCategories(); + await loadExpenses(); } async function loadCategories() { @@ -129,7 +134,7 @@ async function loadCategories() { throw new Error('Failed to load categories'); } - const categories = await response.json(); + categories = await response.json(); // Clear loading option categorySelect.innerHTML = ''; @@ -152,3 +157,89 @@ async function loadCategories() { categorySelect.innerHTML = ''; } } + +async function loadExpenses() { + const token = localStorage.getItem(TOKEN_KEY); + const listContainer = document.getElementById('expense-list'); + + try { + const response = await fetch('/api/expenses', { + method: 'GET', + headers: { + 'Authorization': `Bearer ${token}` + } + }); + + if (!response.ok) { + throw new Error('Failed to load expenses'); + } + + const expenses = await response.json(); + renderExpenses(expenses); + } catch (error) { + console.error('Error loading expenses:', error); + listContainer.innerHTML = '
Error loading expenses
'; + } +} + +function createExpenseCard(expense) { + const category = categories.find(c => c.id === expense.cid); + const categoryName = category ? category.name : 'Unknown'; + const amount = (expense.value / 100).toFixed(2); + const timestamp = new Date(expense.ts).toLocaleString(); + + // Create card structure + const item = document.createElement('div'); + item.className = 'expense-item'; + item.innerHTML = ` +No expenses recorded
'; + return; + } + + listContainer.innerHTML = ''; + expenses.forEach(expense => { + const card = createExpenseCard(expense); + listContainer.appendChild(card); + }); +} + +function addExpenseToList(expense) { + const listContainer = document.getElementById('expense-list'); + + // Remove empty state if it exists + const emptyState = listContainer.querySelector('.empty-state'); + if (emptyState) { + listContainer.innerHTML = ''; + } + + const card = createExpenseCard(expense); + listContainer.insertAdjacentElement('afterbegin', card); +} diff --git a/mft/static/index.html b/mft/static/index.html index d0fc67b..a985ee2 100644 --- a/mft/static/index.html +++ b/mft/static/index.html @@ -44,6 +44,11 @@ + +