Working well enough

This commit is contained in:
2025-07-20 18:47:14 -04:00
parent 701715083f
commit 90a57f8b14
3 changed files with 71 additions and 59 deletions

View File

@ -96,12 +96,14 @@ export async function getBudgetTransactions(id) {
from budget_transaction from budget_transaction
join transaction on budget_transaction.transaction_id = transaction.id join transaction on budget_transaction.transaction_id = transaction.id
where budget_transaction.budget_id = ${id} where budget_transaction.budget_id = ${id}
order by transaction.posted desc order by transaction.date desc
`; `;
console.log(`Fetched ${transactions.length} transactions for budget ${id}`); console.log(`Fetched ${transactions.length} transactions for budget ${id}`);
// transactions = Result [{ id: 1, posted: 1633036800, amount: 50.00, description: "Grocery Store", pending: false, notes: "Weekly groceries" }, ...] // transactions = Result [{ id: 1, posted: 1633036800, amount: 50.00, description: "Grocery Store", pending: false, notes: "Weekly groceries" }, ...]
return { transactions }; return { transactions };
} catch { } catch (error) {
console.error(`Error fetching transactions for budget ${id}`);
console.error(error);
return []; return [];
} }
} }
@ -109,9 +111,9 @@ export async function getBudgetTransactions(id) {
export async function updateBudgetTransaction(id, amount, notes) { export async function updateBudgetTransaction(id, amount, notes) {
// Delete a transaction from a budget // Delete a transaction from a budget
const result = await db` const result = await db`
update from budget_transaction update budget_transaction
where id= ${id}
SET amount = ${amount}, notes = ${notes} SET amount = ${amount}, notes = ${notes}
where id= ${id}
`; `;
// result = Result [{ id: 1 }] // result = Result [{ id: 1 }]
return result; return result;

View File

@ -19,11 +19,11 @@ export async function PATCH({ params, request }) {
const { slug } = params; const { slug } = params;
let body = await request.json(); let body = await request.json();
const { amount, notes } = body; const { amount, notes, transactionId } = body;
console.log({ slug, transactionId, amount }); console.log({ slug, transactionId, amount });
// Call the deleteBudget function from db.js (budgetId, transactionId, amount) // Call the deleteBudget function from db.js (budgetId, transactionId, amount)
return updateBudgetTransaction(slug, amount, notes) return updateBudgetTransaction(transactionId, amount, notes)
.then(() => new Response(`Budget transaction updated successfully`, { status: 200 })) .then(() => new Response(`Budget transaction updated successfully`, { status: 200 }))
.catch( .catch(
(err) => new Response(`Error updating transaction in budget ${err.message}`, { status: 500 }) (err) => new Response(`Error updating transaction in budget ${err.message}`, { status: 500 })

View File

@ -1,18 +1,27 @@
<script> <script>
import { EditSymbol } from '$lib/editSymbol.svelte'; import { EditSymbol } from '$lib/editSymbol.svelte';
import { TrashBin } from '$lib/trashbin.svelte'; import { TrashBin } from '$lib/trashbin.svelte';
import { loadingModal } from '$lib/loadingModal.svelte';
import { getContext } from 'svelte';
import { invalidate, invalidateAll } from '$app/navigation';
let { data } = $props(); let { data } = $props();
const addToast = getContext('addToast');
let budget = $derived(data.budget); let budget = $derived(data.budget);
let transactions = $derived(data.transactions.transactions || []); let transactions = $derived(data.transactions.transactions || []);
let newData = $state({ let newData = $state({
amount: 0, amount: 0,
notes: '' notes: '',
name: '',
id: null
}); });
let toDelete = $state(null); let toDelete = $state('');
let toDeleteName = $state(''); let toDeleteName = $state('');
let loading = $state(false);
async function saveTransaction() { async function saveTransaction() {
loading = true;
EditBudgetTransactionModal.close();
let res = await fetch(`/api/budget/${budget.id}/transaction`, { let res = await fetch(`/api/budget/${budget.id}/transaction`, {
method: 'PATCH', method: 'PATCH',
headers: { headers: {
@ -20,14 +29,27 @@
}, },
body: JSON.stringify({ body: JSON.stringify({
amount: $state.snapshot(newData.amount), amount: $state.snapshot(newData.amount),
notes: $state.snapshot(newData.notes) notes: $state.snapshot(newData.notes),
transactionId: $state.snapshot(newData.id)
}) })
}); });
loading = false;
console.log(res.ok);
if (res.ok) {
// Optionally, you can refresh the UI or show a success message
addToast('Transaction updated successfully', 'success');
invalidateAll();
} else {
console.error('Failed to update transaction');
addToast('Failed to update transaction', 'error');
}
} }
function edit(transaction) { function edit(transaction) {
newData.amount = transaction.budget_amount; newData.amount = transaction.budget_amount;
newData.name = transaction.description;
newData.notes = transaction.notes || ''; newData.notes = transaction.notes || '';
newData.id = transaction.budget_transaction_id;
EditBudgetTransactionModal.showModal(); EditBudgetTransactionModal.showModal();
} }
@ -42,7 +64,7 @@
} }
function deleteTransaction(transaction) { function deleteTransaction(transaction) {
toDelete = transaction; toDelete = transaction.budget_transaction_id;
DeleteTransactionModal.showModal(); DeleteTransactionModal.showModal();
} }
</script> </script>
@ -71,56 +93,36 @@
<div class="w-64 grow">{budget.amount}</div> <div class="w-64 grow">{budget.amount}</div>
</div> </div>
<div class=""> <ul class="list bg-base-100 rounded-box shadow-md">
<h2>Notes:</h2> {#each transactions as tras}
<p>{budget.notes}</p> <li class="list-row">
</div> <div>
<div>{tras.description}</div>
<div class="text-xs uppercase font-semibold opacity-60">
{tras.date.toDateString()}
</div>
</div>
<table class="overflow-x-auto rounded-box border border-base-content/5 bg-base-100"> <div class="text-center">{tras.notes}</div>
<thead>
<tr class="">
<th>Date</th>
<th>Description</th>
<th>Amount</th>
<th>Notes</th>
<th></th>
</tr>
</thead>
<tbody>
{#each transactions as txn}
<tr>
<td>{txn.date.toDateString()}</td>
<td>{txn.description}</td>
<td>${txn.budget_amount}</td>
<td>
{#if txn.notes}
<span>{txn.notes}</span>
{:else}
<span class="text-gray-500">No notes</span>
{/if}
</td>
<td <div class="text-lg uppercase font-semibold text-right w-32">{tras.budget_amount}</div>
><button class="btn btn-square btn-ghost" onclick={() => edit(txn)} <div>
<button class="btn btn-square btn-ghost" onclick={() => edit(tras)}
>{@render EditSymbol()}</button >{@render EditSymbol()}</button
></td
><td
><button class="btn btn-square btn-ghost" onclick={() => deleteTransaction(txn)}
>{@render TrashBin()}</button
></td
></tr
> >
</div>
<div>
<button class="btn btn-square btn-ghost" onclick={() => deleteTransaction(tras)}
>{@render TrashBin()}</button
>
</div>
</li>
{/each} {/each}
{#if transactions.length === 0} </ul>
<tr>
<td colspan="3">No transactions found.</td>
</tr>
{/if}
</tbody>
</table>
<dialog id="EditBudgetTransactionModal" class="modal"> <dialog id="EditBudgetTransactionModal" class="modal">
<div class="modal-box"> <div class="modal-box">
<h1>{newData.name}</h1>
<fieldset class="fieldset bg-base-200 border-base-300 rounded-box w-xs border p-4"> <fieldset class="fieldset bg-base-200 border-base-300 rounded-box w-xs border p-4">
<legend class="fieldset-legend">Edit</legend> <legend class="fieldset-legend">Edit</legend>
@ -159,7 +161,8 @@
<dialog id="DeleteTransactionModal" class="modal"> <dialog id="DeleteTransactionModal" class="modal">
<div class="modal-box"> <div class="modal-box">
<h1>Are you sure you want to delete {toDelete?.description}?</h1> <p>Are you sure you want to delete</p>
<span>{toDelete}</span>
<p>Type it in the box to confirm</p> <p>Type it in the box to confirm</p>
<input <input
bind:value={toDeleteName} bind:value={toDeleteName}
@ -170,19 +173,22 @@
<button <button
class="btn btn-error mt-4" class="btn btn-error mt-4"
onclick={async () => { onclick={async () => {
if (toDelete.description === toDeleteName) { if (toDelete == toDeleteName) {
let res = await fetch(`/api/budget/${toDelete.budget_transaction_id}/transaction/`, { let res = await fetch(`/api/budget/${toDelete}/transaction/`, {
method: 'DELETE' method: 'DELETE'
}); });
if (res.ok) { if (res.ok) {
console.log('Rule deleted successfully'); console.log('Rule deleted successfully');
DeleteTransactionModal.close(); DeleteTransactionModal.close();
location.reload(); invalidateAll();
addToast('Transaction deleted successfully', 'success');
} else { } else {
console.error('Failed to delete transaction'); console.error('Failed to delete transaction');
addToast('Failed to delete transaction', 'error');
} }
} else { } else {
console.error('Name does not match'); console.error('Name does not match');
addToast('Name does not match', 'warning');
} }
}}>Delete</button }}>Delete</button
> >
@ -191,3 +197,7 @@
<button>close</button> <button>close</button>
</form> </form>
</dialog> </dialog>
{#if loading}
{@render loadingModal()}
{/if}