feat: show committed goals in fixed costs panel
Committed goals now appear in the Fixed Costs panel on the dashboard with a "committed goal" label, and the total line uses TotalCommittedCents (fixed costs + goal contributions) instead of total monthly expenses. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
2324f62721
commit
bfd5f62a7a
@ -324,7 +324,7 @@ func (h *Handler) Dashboard(w http.ResponseWriter, r *http.Request) {
|
||||
// disposable income = income - fixed recurring
|
||||
disposableIncome := thisMonthIncome - totalFixedCents
|
||||
|
||||
// deduct committed goal contributions from disposable
|
||||
// deduct committed goal contributions from disposable and add to fixed costs list
|
||||
committedGoalsCents := int64(0)
|
||||
if goals, err := h.store.getGoals(ctx, a.UserID); err == nil {
|
||||
now2 := time.Now()
|
||||
@ -340,10 +340,17 @@ func (h *Handler) Dashboard(w http.ResponseWriter, r *http.Request) {
|
||||
if ml < 1 {
|
||||
ml = 1
|
||||
}
|
||||
committedGoalsCents += remaining / ml
|
||||
monthly := remaining / ml
|
||||
committedGoalsCents += monthly
|
||||
recurringExpenses = append(recurringExpenses, RecurringExpense{
|
||||
Category: g.Name,
|
||||
MonthlyCents: monthly,
|
||||
IsGoal: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
disposableIncome -= committedGoalsCents
|
||||
totalCommittedCents := totalFixedCents + committedGoalsCents
|
||||
|
||||
// variable spend so far this month (non-fixed categories, expenses only)
|
||||
variableSpent := int64(0)
|
||||
@ -450,6 +457,7 @@ func (h *Handler) Dashboard(w http.ResponseWriter, r *http.Request) {
|
||||
RecurringExpenses: recurringExpenses,
|
||||
BankShouldBe: bankShouldBe,
|
||||
SafetyBufferCents: safetyBuffer,
|
||||
TotalCommittedCents: totalCommittedCents,
|
||||
SavingsRatePct: savingsRatePct,
|
||||
LastMonthSavingsRatePct: lastMonthSavingsRatePct,
|
||||
PortfolioValueCents: portfolioValueCents,
|
||||
|
||||
@ -113,8 +113,9 @@ var FixedCategories = map[string]bool{
|
||||
}
|
||||
|
||||
type RecurringExpense struct {
|
||||
Category string
|
||||
Category string
|
||||
MonthlyCents int64
|
||||
IsGoal bool // true when this entry comes from a committed goal
|
||||
}
|
||||
|
||||
type DashboardData struct {
|
||||
@ -140,8 +141,9 @@ type DashboardData struct {
|
||||
MonthSpentPct int // % of disposable already spent
|
||||
|
||||
RecurringExpenses []RecurringExpense
|
||||
BankShouldBe int64 // sum of upcoming fixed costs + safety buffer
|
||||
SafetyBufferCents int64
|
||||
BankShouldBe int64
|
||||
SafetyBufferCents int64
|
||||
TotalCommittedCents int64 // sum of all fixed costs + committed goals
|
||||
|
||||
SavingsRatePct int // savings / income * 100 this month
|
||||
LastMonthSavingsRatePct int
|
||||
|
||||
@ -236,10 +236,14 @@
|
||||
{{$color := index $d.CategoryColors .Category}}
|
||||
<div style="display:flex; align-items:center; justify-content:space-between; padding:10px 0; border-bottom:1px solid var(--border);">
|
||||
<div style="display:flex; align-items:center; gap:10px;">
|
||||
{{if $color}}<span style="width:9px; height:9px; border-radius:50%; background:{{$color}}; flex-shrink:0; display:inline-block;"></span>{{end}}
|
||||
{{if .IsGoal}}
|
||||
<span style="width:9px; height:9px; border-radius:50%; background:var(--accent); flex-shrink:0; display:inline-block;"></span>
|
||||
{{else if $color}}
|
||||
<span style="width:9px; height:9px; border-radius:50%; background:{{$color}}; flex-shrink:0; display:inline-block;"></span>
|
||||
{{end}}
|
||||
<div>
|
||||
<div style="font-size:13px; font-weight:500; color:var(--text);">{{.Category}}</div>
|
||||
<div style="font-size:11px; color:var(--text3);">committed monthly cost</div>
|
||||
<div style="font-size:11px; color:var(--text3);">{{if .IsGoal}}committed goal{{else}}recurring expense{{end}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="text-align:right;">
|
||||
@ -249,8 +253,9 @@
|
||||
</div>
|
||||
{{end}}
|
||||
<div style="display:flex; justify-content:space-between; align-items:center; padding:12px 0 0 0;">
|
||||
<span style="font-size:13px; font-weight:500; color:var(--text);">Total fixed</span>
|
||||
<span style="font-size:15px; font-weight:600; color:var(--red);">− €{{cents $d.BankShouldBe}}</span>
|
||||
<span style="font-size:13px; font-weight:500; color:var(--text);">Total committed</span>
|
||||
<span class="animate-counter" style="font-size:15px; font-weight:600; color:var(--red);"
|
||||
data-target="{{$d.TotalCommittedCents}}" data-prefix="€">€0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user