chore: show available funds in transfer funds page
All checks were successful
Deploy / build-and-deploy (push) Successful in 1m29s

This commit is contained in:
juancwu 2026-05-04 03:26:49 +00:00
commit 4be5385db7
2 changed files with 44 additions and 0 deletions

View file

@ -1535,6 +1535,13 @@ func (h *spaceHandler) SpaceCreateTransferPage(w http.ResponseWriter, r *http.Re
return
}
allocSummary, err := h.allocationService.SummaryForAccount(accountID)
if err != nil {
slog.Error("failed to load allocation summary", "error", err, "account_id", accountID)
ui.RenderError(w, r, "Failed to load page", http.StatusInternalServerError)
return
}
ui.Render(w, r, pages.SpaceCreateTransferPage(pages.SpaceCreateTransferPageProps{
SpaceID: spaceID,
SpaceName: space.Name,
@ -1544,6 +1551,9 @@ func (h *spaceHandler) SpaceCreateTransferPage(w http.ResponseWriter, r *http.Re
SpaceID: spaceID,
SourceAccountID: accountID,
DestAccounts: dests,
SourceAvailable: allocSummary.Available.StringFixedBank(2),
SourceAllocated: allocSummary.Allocated.StringFixedBank(2),
SourceOverflow: allocSummary.Overflow,
Date: time.Now().Format("2006-01-02"),
},
}))
@ -1583,6 +1593,14 @@ func (h *spaceHandler) HandleCreateTransfer(w http.ResponseWriter, r *http.Reque
Description: descriptionInput,
}
if allocSummary, err := h.allocationService.SummaryForAccount(accountID); err != nil {
slog.Error("failed to load allocation summary", "error", err, "account_id", accountID)
} else {
formProps.SourceAvailable = allocSummary.Available.StringFixedBank(2)
formProps.SourceAllocated = allocSummary.Allocated.StringFixedBank(2)
formProps.SourceOverflow = allocSummary.Overflow
}
hasErr := false
if titleInput == "" {
formProps.TitleErr = "Title is required."

View file

@ -7,6 +7,7 @@ import "git.juancwu.dev/juancwu/budgit/internal/ui/components/card"
import "git.juancwu.dev/juancwu/budgit/internal/ui/components/form"
import "git.juancwu.dev/juancwu/budgit/internal/ui/components/input"
import "git.juancwu.dev/juancwu/budgit/internal/ui/components/textarea"
import "git.juancwu.dev/juancwu/budgit/internal/ui/utils"
type CreateTransferProps struct {
SpaceID string
@ -16,6 +17,12 @@ type CreateTransferProps struct {
// can transfer to. Excludes the source account.
DestAccounts []*model.Account
// SourceAvailable / SourceAllocated are the source account's unallocated
// and allocated cash, formatted as plain decimal strings (e.g. "1234.50").
SourceAvailable string
SourceAllocated string
SourceOverflow bool
Title string
Amount string
DestAccountID string
@ -33,6 +40,25 @@ templ CreateTransfer(props CreateTransferProps) {
<form hx-post={ routeurl.URL("action.app.spaces.space.accounts.account.transfers.create", "spaceID", props.SpaceID, "accountID", props.SourceAccountID) }>
@card.Card(card.Props{Class: "rounded-sm"}) {
@card.Content(card.ContentProps{Class: "p-4 space-y-4"}) {
if props.SourceAvailable != "" {
{{
availClasses := []string{"text-2xl font-bold"}
if props.SourceOverflow {
availClasses = append(availClasses, "text-red-600 dark:text-red-400")
}
availFormatted, _ := utils.FormatDecimalWithThousands(props.SourceAvailable)
allocFormatted, _ := utils.FormatDecimalWithThousands(props.SourceAllocated)
}}
<div class="flex flex-col sm:flex-row sm:items-end sm:justify-between gap-2 border rounded-md p-4 bg-muted/30">
<div>
<p class="text-xs text-muted-foreground uppercase tracking-wide">Available</p>
<p class={ utils.TwMerge(availClasses...) }>${ availFormatted }</p>
</div>
<p class="text-sm text-muted-foreground">
Allocated: ${ allocFormatted }
</p>
</div>
}
if props.GeneralErr != "" {
@form.Message(form.MessageProps{Variant: form.MessageVariantError}) {
{ props.GeneralErr }