add expenses management

This commit is contained in:
juancwu 2026-01-14 20:40:36 +00:00
commit f8ddf152e4
16 changed files with 611 additions and 29 deletions

View file

@ -0,0 +1,77 @@
package pages
import (
"fmt"
"git.juancwu.dev/juancwu/budgit/internal/model"
"git.juancwu.dev/juancwu/budgit/internal/ui/components/button"
"git.juancwu.dev/juancwu/budgit/internal/ui/components/dialog"
"git.juancwu.dev/juancwu/budgit/internal/ui/components/expense"
"git.juancwu.dev/juancwu/budgit/internal/ui/layouts"
)
templ SpaceExpensesPage(space *model.Space, expenses []*model.Expense, balance int, tags []*model.Tag, lists []*model.ShoppingList) {
@layouts.Space("Expenses", space) {
<div class="space-y-4">
<div class="flex justify-between items-center">
<h1 class="text-2xl font-bold">Expenses</h1>
@dialog.Dialog(dialog.Props{ ID: "add-expense-dialog" }) {
@dialog.Trigger() {
@button.Button() {
Add Expense
}
}
@dialog.Content() {
@dialog.Header() {
@dialog.Title() { Add Transaction }
@dialog.Description() {
Add a new expense or top-up to your space.
}
}
@expense.AddExpenseForm(space, tags, lists)
}
}
</div>
// Balance Card
@expense.BalanceCard(balance, false)
// List of expenses
<div id="expenses-list" class="border rounded-lg">
<h2 class="text-lg font-semibold p-4">History</h2>
<div class="divide-y">
if len(expenses) == 0 {
<p class="p-4 text-sm text-muted-foreground">No expenses recorded yet.</p>
}
for _, expense := range expenses {
@ExpenseListItem(expense)
}
</div>
</div>
</div>
}
}
templ ExpenseListItem(expense *model.Expense) {
<div class="p-4 flex justify-between items-center">
<div>
<p class="font-medium">{ expense.Description }</p>
<p class="text-sm text-muted-foreground">{ expense.Date.Format("Jan 02, 2006") }</p>
</div>
<div>
if expense.Type == model.ExpenseTypeExpense {
<p class="font-bold text-destructive">
- { fmt.Sprintf("$%.2f", float64(expense.AmountCents)/100.0) }
</p>
} else {
<p class="font-bold text-green-500">
+ { fmt.Sprintf("$%.2f", float64(expense.AmountCents)/100.0) }
</p>
}
</div>
</div>
}
templ ExpenseCreatedResponse(newExpense *model.Expense, balance int) {
@ExpenseListItem(newExpense)
@expense.BalanceCard(balance, true)
}