whisper-money/resources/js/components/ui
Víctor Falcón 9a458b1031
feat(ai): manage AI consent outside onboarding with live backfill (#591)
## Summary

Lets existing (non-onboarding) users discover and manage AI
categorization, gated behind a new Pennant feature flag. When a flagged
paid user grants consent, every uncategorized transaction is categorized
in the background with live, on-screen feedback.

Enable per user: `php artisan feature:enable AiConsentSettings
user@example.com`

## What's included

**Feature flag**
- New `AiConsentSettings` Pennant flag (off by default), exposed to the
frontend via the shared `features` prop.

**Billing settings (`/settings/billing`)**
- When the flag is active, a section to grant or revoke AI consent
(checkbox → `POST`/`DELETE /ai/consent`).

**Transactions page**
- A consent prompt rendered as the first row of the transactions table
(new `DataTable` `topRow` slot), styled with the shared gradient
`AiSparkleIcon`. Only shown to paid users with the flag who haven't
consented yet.
- An inline "Enable AI" button records consent without leaving the page.

**Backfill on consent**
- Granting consent dispatches a queued
`CategorizeUncategorizedTransactionsJob` that categorizes all of the
user's uncategorized transactions, **most recent first**, recording
progress in the cache.
- The transactions page polls a new status endpoint (`GET
/ai/categorization/{jobId}/status`): visible uncategorized rows show a
spinner + pulse while the backfill runs, categories stream in via
partial reloads, and a toast tracks `processed / total` until
completion.

## Notes / decisions

- **Polling, not websockets** — the project has no broadcasting
configured; this mirrors the existing `ReEvaluateTransactionRules` job +
status-endpoint pattern.
- The backfill job is kept separate from
`CategorizeOnboardingTransactionsJob` so the onboarding pass stays
progress-free (small, commented duplication).
- Reuses the existing `AiCategorizationGate` (config kill-switch + pro
plan + active consent) — free users and disabled-AI never dispatch the
job.
- Not included (YAGNI): cancelling an in-flight backfill on revoke;
persisting the spinner across full page reloads.

## Testing

- New Pest coverage: feature-flag exposure, billing/transactions consent
props, consent-triggered dispatch + gating, the status endpoint
(200/404), job progress recording, and recent-first ordering.
- `php artisan test --exclude-testsuite=Browser` passes (one unrelated,
pre-existing `DashboardTest` failure on `main`).
- Pint, Prettier and ESLint clean.
2026-06-25 10:50:35 +02:00
..
ai-sparkle-icon.tsx feat(ai): share AI sparkle icon and mark AI-generated rules (#538) 2026-06-15 18:22:11 +02:00
alert-dialog.tsx Accounts: new pages to list, and see account details (#13) 2025-12-05 14:33:18 +01:00
alert.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
amount-display.tsx refactor(encryption): strip client-side transaction encryption (#514) 2026-06-20 16:13:26 +00:00
amount-input.tsx chore(frontend): add orphan component detection and remove dead components (#181) 2026-03-02 12:43:27 +01:00
animated-collapse.tsx feat: expand parent categories inline in breakdowns (#486) 2026-06-04 11:19:21 +02:00
avatar.tsx chore(frontend): add orphan component detection and remove dead components (#181) 2026-03-02 12:43:27 +01:00
badge.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
breadcrumb.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
button-group.tsx Bulk actions on transactions 2025-11-10 10:02:28 +00:00
button.tsx ui: add cursor pointer to the buttons 2026-01-07 11:12:03 +01:00
card.tsx feat(ui): add glowing effect to all card components (#170) 2026-03-01 10:56:59 +00:00
chart.tsx fix(chart): hide tooltip on scroll with opacity fade (#320) 2026-04-24 08:28:14 +01:00
checkbox.tsx feat: parent/child category tree (#474) 2026-06-03 19:30:12 +02:00
collapsible.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
command.tsx fix: scroll category combobox to top while searching 2026-01-09 10:02:25 +01:00
context-menu.tsx Context menu to tables 2025-11-15 13:57:10 +01:00
create-button.tsx feat: Integrate EnableBanking as open banking provider (#106) 2026-02-12 09:09:28 +01:00
data-table-pagination.tsx feat: Spanish localization (#74) 2026-02-08 11:58:08 +01:00
data-table-view-options.tsx feat: Spanish localization (#74) 2026-02-08 11:58:08 +01:00
data-table.tsx feat(ai): manage AI consent outside onboarding with live backfill (#591) 2026-06-25 10:50:35 +02:00
dialog.tsx ui(fix): add hasKeyboard prop to dialogs 2025-12-30 07:22:19 +01:00
drawer.tsx Import CSV 2025-11-08 14:17:11 +00:00
dropdown-menu.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
glowing-effect.tsx chore(frontend): add orphan component detection and remove dead components (#181) 2026-03-02 12:43:27 +01:00
input-otp.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
input.tsx Add Budgeting Feature to Track and Manage Spending (#36) 2026-01-21 15:25:50 +01:00
kbd.tsx Adapt for mobile screen 2025-12-09 16:44:56 +01:00
label.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
multi-select.tsx feat: parent/child category tree (#474) 2026-06-03 19:30:12 +02:00
password-input.test.tsx feat(auth): show/hide toggle on password fields (#499) 2026-06-06 11:42:20 +02:00
password-input.tsx feat(auth): show/hide toggle on password fields (#499) 2026-06-06 11:42:20 +02:00
popover.tsx fix: keep iOS popovers below the notch (#282) 2026-04-13 15:19:56 +01:00
progress.tsx feat(dashboard): make top spending categories clickable with transaction filter link (#189) 2026-03-03 11:24:50 +00:00
radio-group.tsx Import CSV 2025-11-08 14:17:11 +00:00
select.tsx fix(ui): app icon visible on light wallpapers + country select overflow on mobile (#162) 2026-02-28 13:41:41 +00:00
separator.tsx Bulk actions on transactions 2025-11-10 10:02:28 +00:00
sheet.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
sidebar.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
skeleton.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
spinner.tsx feat: Spanish localization (#74) 2026-02-08 11:58:08 +01:00
stacked-area-chart.tsx Fix net worth chart config UX and color scheme issues (#250) 2026-03-31 11:19:35 +01:00
stacked-bar-chart.test.tsx fix(chart): mask stacked bar edges (#439) 2026-05-26 17:03:06 +02:00
stacked-bar-chart.tsx fix(chart): mask stacked bar edges (#439) 2026-05-26 17:03:06 +02:00
table.tsx Refactor: Transaction Table Layout and Styling Improvements (#26) 2025-12-14 12:56:05 +01:00
textarea.tsx Transactions page 2025-11-08 23:38:35 +00:00
toggle-group.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
toggle.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
tooltip.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00