fix: overdue badge excludes due today, tooltip with names, larger column labels
This commit is contained in:
parent
46bcf83d22
commit
779ace60dd
|
|
@ -28,6 +28,10 @@
|
||||||
|
|
||||||
- **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.
|
- **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.
|
||||||
|
|
||||||
|
- **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.
|
||||||
|
|
||||||
- **Tracker row keyboard navigation** — Tracker rows (desktop table view) are now keyboard navigable. Each row has `tabIndex={0}`, `data-tracker-row`, `aria-rowindex`, and an `aria-label` announcing the bill name, status, and due day. A `focus-visible:ring-2 ring-primary/60 ring-inset` focus ring appears on keyboard focus only. Key bindings: `↓`/`j` focuses the next row, `↑`/`k` the previous (both cross bucket boundaries via `querySelectorAll('[data-tracker-row]')`), `Enter` opens the edit modal, `P` toggles paid/unpaid (skipped bills ignored, `Ctrl+P`/`Cmd+P` passes through to the browser), `Esc` blurs the row. The `onKeyDown` handler guards against firing on nested interactive elements with `if (e.target !== e.currentTarget) return`.
|
- **Tracker row keyboard navigation** — Tracker rows (desktop table view) are now keyboard navigable. Each row has `tabIndex={0}`, `data-tracker-row`, `aria-rowindex`, and an `aria-label` announcing the bill name, status, and due day. A `focus-visible:ring-2 ring-primary/60 ring-inset` focus ring appears on keyboard focus only. Key bindings: `↓`/`j` focuses the next row, `↑`/`k` the previous (both cross bucket boundaries via `querySelectorAll('[data-tracker-row]')`), `Enter` opens the edit modal, `P` toggles paid/unpaid (skipped bills ignored, `Ctrl+P`/`Cmd+P` passes through to the browser), `Esc` blurs the row. The `onKeyDown` handler guards against firing on nested interactive elements with `if (e.target !== e.currentTarget) return`.
|
||||||
|
|
||||||
- **Bills list query optimised and merchant rule index added** — `GET /api/bills` replaced a correlated `EXISTS(SELECT 1 FROM bill_history_ranges WHERE bill_id = b.id)` per bill row with a single `LEFT JOIN (SELECT DISTINCT bill_id FROM bill_history_ranges) hr`. DB migration `v0.81` adds composite index `idx_bill_merchant_rules_user_bill ON bill_merchant_rules(user_id, bill_id)` — the existing index only covered `user_id`, making the EXISTS check in `GET /api/bills/:id` scan by user then filter by bill; the composite index makes it a direct point lookup. Pagination was not added — the UI depends on all bills being loaded at once and personal-scale data volumes don't warrant it.
|
- **Bills list query optimised and merchant rule index added** — `GET /api/bills` replaced a correlated `EXISTS(SELECT 1 FROM bill_history_ranges WHERE bill_id = b.id)` per bill row with a single `LEFT JOIN (SELECT DISTINCT bill_id FROM bill_history_ranges) hr`. DB migration `v0.81` adds composite index `idx_bill_merchant_rules_user_bill ON bill_merchant_rules(user_id, bill_id)` — the existing index only covered `user_id`, making the EXISTS check in `GET /api/bills/:id` scan by user then filter by bill; the composite index makes it a direct point lookup. Pagination was not added — the UI depends on all bills being loaded at once and personal-scale data volumes don't warrant it.
|
||||||
|
|
|
||||||
|
|
@ -333,7 +333,7 @@ export default function BankSyncSection({ onConnectionChange, cardProps = {} })
|
||||||
const loadBankTracking = useCallback(async () => {
|
const loadBankTracking = useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
const [settings, accounts] = await Promise.all([
|
const [settings, accounts] = await Promise.all([
|
||||||
api.getSettings(),
|
api.settings(),
|
||||||
api.allFinancialAccounts().catch(() => []),
|
api.allFinancialAccounts().catch(() => []),
|
||||||
]);
|
]);
|
||||||
setBtEnabled(settings.bank_tracking_enabled === 'true');
|
setBtEnabled(settings.bank_tracking_enabled === 'true');
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue