kinda there

This commit is contained in:
2025-07-18 23:02:01 -04:00
parent 3e7572f3a3
commit 3225ebb986
28 changed files with 1665 additions and 475 deletions

View File

@ -1,10 +1,13 @@
<script>
import { EditSymbol } from '$lib/editSymbol.svelte';
import { settingsSymbol } from '$lib/settingsSymbol.svelte';
let { data } = $props();
console.log(data);
let trans = $derived(data.transactions);
let budgets = $derived(data.budgets);
let budgetTransactions = $derived(data.budgetTransactions);
let notes = $state('');
let currentTransaction = $state(null);
let account = $derived(data.account);
let currentTransaction = $state({ budget_id: null, amount: 0, notes: '' });
let account = $derived(data.account);
let hide = $derived(account?.hide || false);
let inTotal = $derived(account?.in_total || false);
@ -32,61 +35,34 @@
console.error('Failed to save notes');
}
}
async function saveSettings() {
let res = await fetch(`/api/account/${account.id}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
hide: $state.snapshot(hide),
in_total: $state.snapshot(inTotal)
})
});
if (res.ok) {
settings_modal.close();
// Optionally, you can refresh the account data or show a success message
} else {
console.error('Failed to save settings');
}
}
async function saveSettings() {
let res = await fetch(`/api/account/${account.id}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
hide: $state.snapshot(hide),
in_total: $state.snapshot(inTotal)
})
});
if (res.ok) {
settings_modal.close();
// Optionally, you can refresh the account data or show a success message
} else {
console.error('Failed to save settings');
}
}
</script>
<div class="flex mb-4">
<div class="w-128 flex-none justify-bottom"><h1 class="text-xl font-bold">{account?.name}</h1></div>
<div class="w-64 grow">{account?.balance}</div>
<div class="w-14 flex-none text-right">
<svg onclick={()=>settings_modal.showModal()} fill="#000000" height="20px" width="20px" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 478.703 478.703" xml:space="preserve">
<g>
<g>
<path fill="#FEFEFE" d="M454.2,189.101l-33.6-5.7c-3.5-11.3-8-22.2-13.5-32.6l19.8-27.7c8.4-11.8,7.1-27.9-3.2-38.1l-29.8-29.8
c-5.6-5.6-13-8.7-20.9-8.7c-6.2,0-12.1,1.9-17.1,5.5l-27.8,19.8c-10.8-5.7-22.1-10.4-33.8-13.9l-5.6-33.2
c-2.4-14.3-14.7-24.7-29.2-24.7h-42.1c-14.5,0-26.8,10.4-29.2,24.7l-5.8,34c-11.2,3.5-22.1,8.1-32.5,13.7l-27.5-19.8
c-5-3.6-11-5.5-17.2-5.5c-7.9,0-15.4,3.1-20.9,8.7l-29.9,29.8c-10.2,10.2-11.6,26.3-3.2,38.1l20,28.1
c-5.5,10.5-9.9,21.4-13.3,32.7l-33.2,5.6c-14.3,2.4-24.7,14.7-24.7,29.2v42.1c0,14.5,10.4,26.8,24.7,29.2l34,5.8
c3.5,11.2,8.1,22.1,13.7,32.5l-19.7,27.4c-8.4,11.8-7.1,27.9,3.2,38.1l29.8,29.8c5.6,5.6,13,8.7,20.9,8.7c6.2,0,12.1-1.9,17.1-5.5
l28.1-20c10.1,5.3,20.7,9.6,31.6,13l5.6,33.6c2.4,14.3,14.7,24.7,29.2,24.7h42.2c14.5,0,26.8-10.4,29.2-24.7l5.7-33.6
c11.3-3.5,22.2-8,32.6-13.5l27.7,19.8c5,3.6,11,5.5,17.2,5.5l0,0c7.9,0,15.3-3.1,20.9-8.7l29.8-29.8c10.2-10.2,11.6-26.3,3.2-38.1
l-19.8-27.8c5.5-10.5,10.1-21.4,13.5-32.6l33.6-5.6c14.3-2.4,24.7-14.7,24.7-29.2v-42.1
C478.9,203.801,468.5,191.501,454.2,189.101z M451.9,260.401c0,1.3-0.9,2.4-2.2,2.6l-42,7c-5.3,0.9-9.5,4.8-10.8,9.9
c-3.8,14.7-9.6,28.8-17.4,41.9c-2.7,4.6-2.5,10.3,0.6,14.7l24.7,34.8c0.7,1,0.6,2.5-0.3,3.4l-29.8,29.8c-0.7,0.7-1.4,0.8-1.9,0.8
c-0.6,0-1.1-0.2-1.5-0.5l-34.7-24.7c-4.3-3.1-10.1-3.3-14.7-0.6c-13.1,7.8-27.2,13.6-41.9,17.4c-5.2,1.3-9.1,5.6-9.9,10.8l-7.1,42
c-0.2,1.3-1.3,2.2-2.6,2.2h-42.1c-1.3,0-2.4-0.9-2.6-2.2l-7-42c-0.9-5.3-4.8-9.5-9.9-10.8c-14.3-3.7-28.1-9.4-41-16.8
c-2.1-1.2-4.5-1.8-6.8-1.8c-2.7,0-5.5,0.8-7.8,2.5l-35,24.9c-0.5,0.3-1,0.5-1.5,0.5c-0.4,0-1.2-0.1-1.9-0.8l-29.8-29.8
c-0.9-0.9-1-2.3-0.3-3.4l24.6-34.5c3.1-4.4,3.3-10.2,0.6-14.8c-7.8-13-13.8-27.1-17.6-41.8c-1.4-5.1-5.6-9-10.8-9.9l-42.3-7.2
c-1.3-0.2-2.2-1.3-2.2-2.6v-42.1c0-1.3,0.9-2.4,2.2-2.6l41.7-7c5.3-0.9,9.6-4.8,10.9-10c3.7-14.7,9.4-28.9,17.1-42
c2.7-4.6,2.4-10.3-0.7-14.6l-24.9-35c-0.7-1-0.6-2.5,0.3-3.4l29.8-29.8c0.7-0.7,1.4-0.8,1.9-0.8c0.6,0,1.1,0.2,1.5,0.5l34.5,24.6
c4.4,3.1,10.2,3.3,14.8,0.6c13-7.8,27.1-13.8,41.8-17.6c5.1-1.4,9-5.6,9.9-10.8l7.2-42.3c0.2-1.3,1.3-2.2,2.6-2.2h42.1
c1.3,0,2.4,0.9,2.6,2.2l7,41.7c0.9,5.3,4.8,9.6,10,10.9c15.1,3.8,29.5,9.7,42.9,17.6c4.6,2.7,10.3,2.5,14.7-0.6l34.5-24.8
c0.5-0.3,1-0.5,1.5-0.5c0.4,0,1.2,0.1,1.9,0.8l29.8,29.8c0.9,0.9,1,2.3,0.3,3.4l-24.7,34.7c-3.1,4.3-3.3,10.1-0.6,14.7
c7.8,13.1,13.6,27.2,17.4,41.9c1.3,5.2,5.6,9.1,10.8,9.9l42,7.1c1.3,0.2,2.2,1.3,2.2,2.6v42.1H451.9z"/>
<path fill="#FEFEFE" d="M239.4,136.001c-57,0-103.3,46.3-103.3,103.3s46.3,103.3,103.3,103.3s103.3-46.3,103.3-103.3S296.4,136.001,239.4,136.001
z M239.4,315.601c-42.1,0-76.3-34.2-76.3-76.3s34.2-76.3,76.3-76.3s76.3,34.2,76.3,76.3S281.5,315.601,239.4,315.601z"/>
</g>
</g>
</svg>
</div>
<div class="w-128 flex-none justify-bottom">
<h1 class="text-xl font-bold">{account?.name}</h1>
</div>
<div class="w-64 grow">{account?.balance}</div>
<div class="w-14 flex-none text-right">
<button class="btn btn-square btn-ghost">{@render settingsSymbol()} </button>
</div>
</div>
<h1>Transcations</h1>
@ -94,18 +70,55 @@
<thead>
<tr>
<th>Date</th>
<th>Payee</th>
<th>Description</th>
<th>Amount</th>
<th>Notes</th>
<th>Budgets</th>
<th></th>
</tr>
</thead>
<tbody>
{#each trans as transaction}
<tr class="hover:bg-base-300" onclick={() => editNotes(transaction)}>
{@const applicableBudgets = budgetTransactions.filter(
(bt) => bt.transaction_id === transaction.id
)}
{@const budgetTotal = applicableBudgets.reduce(
(accumulator, currentValue) => accumulator + Number(currentValue.amount),
0
)}
<tr class="hover:bg-base-300">
<td>{transaction.date.toDateString()}</td>
<td>{transaction.payee ?? ''}</td>
<td>{transaction.description}</td>
<td>{transaction.amount}</td>
<td
><ul class="list bg-base-100 rounded-box shadow-md">
<li class="list-row">Amount: {transaction.amount}</li>
<li class="list-row">Budget: {budgetTotal.toFixed(2)}</li>
<li class="list-row">Remains: {(transaction.amount - budgetTotal).toFixed(2)}</li>
</ul></td
>
<td>{transaction.notes}</td>
<td>
<ul class="list bg-base-100 rounded-box shadow-md">
{#each applicableBudgets as budgetTransaction}
<li class="list-row">
<div class="flex">
<div class="flex-auto w-24">
{budgets.find((b) => b.id === budgetTransaction.budget_id)?.name}
</div>
<div class="flex-auto w-16">${budgetTransaction.amount}</div>
<div class="flex-auto w-48">{budgetTransaction.notes}</div>
</div>
</li>
{/each}
</ul></td
>
<td
><button class="btn btn-square btn-ghost" onclick={() => editNotes(transaction)}
>{@render EditSymbol()}</button
></td
>
</tr>
{/each}
</tbody>
@ -116,14 +129,66 @@
<form method="dialog">
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"></button>
</form>
<h3>{currentTransaction?.description}</h3>
<h4>${currentTransaction?.amount}</h4>
<p>{currentTransaction?.date?.toDateString()}</p>
<div>
<fieldset class="fieldset">
<p class="label">{currentTransaction?.description}</p>
<p class="label">${currentTransaction?.amount}</p>
<p class="label">{currentTransaction?.date?.toDateString()}</p>
<legend class="fieldset-legend">Notes</legend>
<textarea bind:value={notes} class="textarea w-100"></textarea>
</div>
<button onclick={() => saveNotes()} class="btn btn-primary mt-4">Save</button>
<button class="btn btn-neutral" onclick={() => saveNotes()}>Save</button>
<legend class="fieldset-legend">Add to budget</legend>
<select bind:value={currentTransaction.budget_id} class="select">
<option disabled selected>Pick a budget</option>
{#each budgets as budget}
<option value={budget.id}>{budget.name} - {budget.sum}</option>
{/each}
</select>
<legend class="fieldset-legend">Amount</legend>
<input
bind:value={currentTransaction.amount}
type="number"
class="input validator"
required
placeholder="Amount"
title="Amount"
/>
<legend class="fieldset-legend">Notes</legend>
<textarea bind:value={currentTransaction.notes} class="textarea w-100"></textarea>
<p class="validator-hint">Must a sensible number</p>
<button
class="btn btn-primary"
onclick={() => {
if (budget_id) {
fetch(`/api/budget/${budget_id}/transaction`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
transactionId: currentTransaction.id,
amount: currentTransaction.amount,
notes: currentTransaction.notes
})
}).then((res) => {
if (res.ok) {
// Optionally, you can refresh the UI or show a success message
console.log('Transaction added to budget successfully');
} else {
console.error('Failed to add transaction to budget');
}
});
} else {
console.error('No budget selected');
}
}}>Add to Budget</button
>
</fieldset>
</div>
<form method="dialog" class="modal-backdrop">
<button>close</button>
</form>
</dialog>
<dialog id="settings_modal" class="modal">
@ -138,11 +203,14 @@
<input type="checkbox" bind:checked={hide} class="toggle" />
Hide
</label>
<label class="label">
<label class="label">
<input type="checkbox" bind:checked={inTotal} class="toggle" />
Use in total
</label>
</fieldset>
<button onclick={() => saveSettings()} class="btn btn-primary mt-4">Save</button>
</div>
<form method="dialog" class="modal-backdrop">
<button>close</button>
</form>
</dialog>