fix: bank tracking pending deduction corrected, projected month-end balance, settings loading fix
This commit is contained in:
parent
ccdd16a626
commit
48f5577031
|
|
@ -28,6 +28,12 @@
|
|||
|
||||
- **Pin Due — urgent bills float to top of tracker** — A "Pin Due" toggle button in the TrackerPage header sorts overdue and due-soon bills to the top of each bucket when enabled. Priority order: `missed` → `late` → `due_soon` → `upcoming` → everything else; ties broken by `due_day`. The sort runs after filtering but before the bucket split, so each half-month bucket is sorted independently. The button uses `variant="default"` (solid) when active and `variant="outline"` when off so the current mode is always visible. Preference persists across sessions via `localStorage` under `tracker_pin_upcoming`. Drag reorder is automatically disabled while the toggle is on (`reorderEnabled` now also requires `!pinUpcoming`) since the two modes conflict.
|
||||
|
||||
- **Bank tracking pending deduction corrected — no double-counting** — The pending payments window was subtracting all recent payments regardless of source, including bank-synced ones (`payment_source = 'provider_sync'`). Since the live bank balance already reflects those outgoing transactions, subtracting them again produced a balance ~$2k lower than reality. Fixed in both `trackerService.js` and `summary.js` by adding `AND (p.payment_source IS NULL OR p.payment_source != 'provider_sync')` to the pending query. Only manually-entered payments and transaction-matched payments are now counted as pending — those are payments the user recorded in the tracker before the bank has seen them. The `pending_cleared` badge on tracker rows was given the same fix. Additionally, `b.name` was missing from the `SELECT` in `getOverdueCount`, causing the tooltip to show `null` names — corrected.
|
||||
|
||||
- **Bank tracking: projected month-end balance added** — The CalendarPage Monthly Money Map (bank mode) now shows a dedicated "Projected Month-End Balance" row below the four metrics. It displays the full equation inline — `$5,461 bank − $1,737 pending − $3,696 remaining bills` — so the source of the number is always visible. The row uses a green/red border depending on whether the projection is positive or negative. The TrackerPage Starting card hint also updated from `account_name · live balance` to `account_name · projected $X after bills` so the projection is visible without navigating to Calendar.
|
||||
|
||||
- **Bank tracking settings and account picker fixed** — The `loadBankTracking` function in `BankSyncSection` called `api.getSettings()` but the API method is `api.settings()`. The wrong name threw `TypeError: api.getSettings is not a function`, silently caught by the outer `catch {}`, so neither the toggle state nor the account list ever loaded. Renamed to `api.settings()`. All 19 financial accounts now appear in the picker and the enabled/account/pending-days settings persist correctly across page loads.
|
||||
|
||||
- **Overdue badge: "due today" no longer counts as overdue + tooltip added** — `getOverdueCount` changed `dueDate > todayStr` to `dueDate >= todayStr` so bills due today are not counted as past due — only bills strictly in the past trigger the badge. The function now also returns `names: [...]` alongside the count. Both the sidebar `TrackerMenu` (desktop) and `NavPill` (mobile) wrap the badge in a `<Tooltip>` that shows "2 past due · Discord Nitro · Camry" on hover, so the number is immediately explained without navigating anywhere. Up to 5 names are shown with a "+N more" overflow line.
|
||||
|
||||
- **Column labels larger and lighter in tracker table** — `TableHead` elements in `TrackerBucket` changed from `text-[10px] font-semibold tracking-widest` to `text-xs font-medium tracking-wider`. Size increased from 10 px to 12 px for readability; weight dropped from semibold to medium so the labels don't visually compete with the bold bill name text in each row.
|
||||
|
|
|
|||
|
|
@ -168,6 +168,32 @@ function MoneyMap({ summaryData, loading }) {
|
|||
</div>
|
||||
)}
|
||||
|
||||
{bankMode && (
|
||||
<div className={cn(
|
||||
'flex items-center justify-between gap-3 rounded-xl border px-4 py-3',
|
||||
Number(bt.remaining || 0) >= 0
|
||||
? 'border-emerald-500/25 bg-emerald-500/5'
|
||||
: 'border-destructive/25 bg-destructive/5',
|
||||
)}>
|
||||
<div className="space-y-0.5">
|
||||
<p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
|
||||
Projected Month-End Balance
|
||||
</p>
|
||||
<p className="text-[11px] text-muted-foreground/70">
|
||||
{fmt(bt.balance || 0)} bank
|
||||
{Number(bt.pending_payments || 0) > 0 && ` − ${fmt(bt.pending_payments)} pending`}
|
||||
{` − ${fmt(bt.unpaid_this_month || 0)} remaining bills`}
|
||||
</p>
|
||||
</div>
|
||||
<p className={cn(
|
||||
'tracker-number text-2xl font-bold tabular-nums shrink-0',
|
||||
Number(bt.remaining || 0) >= 0 ? 'text-emerald-600 dark:text-emerald-400' : 'text-destructive',
|
||||
)}>
|
||||
{Number(bt.remaining || 0) < 0 ? '−' : ''}{fmt(Math.abs(Number(bt.remaining || 0)))}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{bankMode && bt.last_updated && (
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Balance last updated: {new Date(bt.last_updated).toLocaleString()}
|
||||
|
|
|
|||
|
|
@ -489,7 +489,11 @@ export default function TrackerPage() {
|
|||
type="starting"
|
||||
value={summary.total_starting}
|
||||
hint={(() => {
|
||||
if (bankTracking?.enabled) return `${bankTracking.account_name} · live balance`;
|
||||
if (bankTracking?.enabled) {
|
||||
const proj = Number(bankTracking.remaining ?? 0);
|
||||
const sign = proj < 0 ? '−' : '';
|
||||
return `${bankTracking.account_name} · projected ${sign}${fmt(Math.abs(proj))} after bills`;
|
||||
}
|
||||
if (!summary.has_starting_amounts) return 'Set monthly starting cash';
|
||||
if (cashflow?.has_data && cashflow.period_projected !== undefined) {
|
||||
const proj = Number(cashflow.period_projected);
|
||||
|
|
|
|||
Loading…
Reference in New Issue