whisper-money/resources/js/components
Víctor Falcón 12cab755e3
feat(roadmap): add a public roadmap page mirrored from UserJot (#778)
## What

A public `/roadmap` page in the landing's own style, listing the UserJot
board so visitors can see what is being built, and links to it from the
landing header (before GitHub and Discord) and footer.

<!-- Drop pr-roadmap-light.png and pr-roadmap-dark.png here -->

## How

UserJot has no public API, so the page reads the same tRPC endpoints its
own frontend calls (`x1.roadmap.getPage`, `x1.submission.getPage`, both
keyed by an `x-host` header) and caches the whole result for a day.

- **Dates.** The roadmap listing only knows when a submission was
*opened*, which for shipped work is months before it moved — nearly
every item would read "Jan 2026". The date a submission last changed
status lives on its detail endpoint, so those are fetched concurrently
with `Http::pool` and fall back to the creation date when a submission
has never moved.
- **Order.** Planned → in progress → shipped, and within a status the
most recently moved item first.
- **Bodies.** Submissions are written in Markdown by whoever opened
them. Rather than pull in a renderer for text we only show three lines
of, the emphasis markers are stripped and the body is collapsed into a
single paragraph, clamped with `line-clamp-3`. Each title links to its
ticket (new tab), so the full text is one click away.
- **Failure.** An unreachable UserJot renders the empty state with a
link to the board, not a 500, and the failure is not cached.

The page is also in `sitemap.xml`.

## Notes

- The mobile pill header hides its GitHub and Discord buttons (`hidden
sm:flex` inside an `sm:hidden` container), so a link there would never
be visible. The footer link is how mobile visitors reach the page; its
row got `flex-wrap` since it now holds five items.
- No pagination: there are 20 submissions and the request limit is 50.

## Testing
<img width="1280" height="1100" alt="pr-roadmap-dark"
src="https://github.com/user-attachments/assets/db07cb16-7e0f-4de8-960b-464bf0419d59"
/>
<img width="1280" height="1100" alt="pr-roadmap-light"
src="https://github.com/user-attachments/assets/a107e5bb-2deb-4f37-b511-7c188552c1e1"
/>

- `tests/Feature/RoadmapTest.php` covers status grouping, the
status-change date and its fallback, the ordering, the one-fetch-per-day
cache, and the unreachable-UserJot empty state.
- QA'd in Chrome: desktop light and dark, and mobile.
- `pint`, `prettier`, `eslint`, `jscpd` and `crap` all clean.
2026-08-11 14:14:59 +00:00
..
accounts feat(accounts): count shared accounts at the owner's percentage (#750) 2026-08-11 13:26:54 +00:00
automation-rules fix(security): scope job-status endpoints to owner + feature-area fixes (#627) 2026-07-03 14:49:32 +02:00
budgets feat: add catch-all budgets (#527) 2026-06-15 16:07:19 +00:00
cashflow feat(analysis): per-category 12-month spending drawer (#519) 2026-06-11 09:52:53 +02:00
categories refactor(frontend): call backend routes through Wayfinder instead of literal URLs (#772) 2026-08-11 13:26:10 +00:00
charts feat(cashflow): expand income categories and fix Sankey label overlap (#672) 2026-07-13 07:28:14 +00:00
dashboard refactor(frontend): call backend routes through Wayfinder instead of literal URLs (#772) 2026-08-11 13:26:10 +00:00
icons Subscriptions (#15) 2025-12-06 19:09:56 +01:00
integration-requests feat(integration-requests): add done status and fix review command crash on orphaned author (#601) 2026-06-27 14:42:09 +00:00
labels refactor(js): use InputError for inline form errors (#483) 2026-06-03 19:01:21 +02:00
landing feat(landing): stop auto-redirecting signed-in visitors to the dashboard (#777)a 2026-08-11 14:02:18 +00:00
onboarding fix(onboarding): don't trap users on the syncing step when a bank sync fails (#745) 2026-08-09 18:40:49 +02:00
open-banking feat: reuse the upgrade modal at more upsell points and attribute revenue (#699) 2026-07-18 12:53:20 +00:00
partials feat(roadmap): add a public roadmap page mirrored from UserJot (#778) 2026-08-11 14:14:59 +00:00
shared refactor(settings): move the last two settings tables onto the shared table and hook (#775) 2026-08-11 13:54:18 +00:00
subscription feat: reuse the upgrade modal at more upsell points and attribute revenue (#699) 2026-07-18 12:53:20 +00:00
transactions refactor(frontend): call backend routes through Wayfinder instead of literal URLs (#772) 2026-08-11 13:26:10 +00:00
ui fix(dashboard): render negative net worth as a downward bar (#722) 2026-07-22 09:32:18 +00:00
alert-error.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
app-content.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
app-error-boundary.test.tsx fix(ui): show a recoverable screen instead of a blank page when render throws (#758) 2026-08-10 15:02:39 +00:00
app-error-boundary.tsx feat(landing): stop auto-redirecting signed-in visitors to the dashboard (#777)a 2026-08-11 14:02:18 +00:00
app-logo-icon.tsx refactor(encryption): strip client-side transaction encryption (#514) 2026-06-20 16:13:26 +00:00
app-logo.tsx Add animated logo icon that transitions based on encryption key state 2025-12-12 11:24:42 +01:00
app-shell.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
app-sidebar-header.tsx fix: keep iOS content below the notch (#280) 2026-04-13 13:59:05 +01:00
app-sidebar.tsx fix: move community link to user menu (#442) 2026-05-27 17:39:26 +02:00
appearance-tabs.tsx feat: Spanish localization (#74) 2026-02-08 11:58:08 +01:00
bank-logo.tsx feat: Integrate EnableBanking as open banking provider (#106) 2026-02-12 09:09:28 +01:00
breadcrumbs.tsx feat: Spanish localization (#74) 2026-02-08 11:58:08 +01:00
delete-user.tsx fix(account): block deletion while subscription or trial is active (#531) 2026-06-14 20:46:44 +02:00
encryption-key-button.tsx feat: Spanish localization (#74) 2026-02-08 11:58:08 +01:00
heading-small.tsx Add Budgeting Feature to Track and Manage Spending (#36) 2026-01-21 15:25:50 +01:00
heading.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
icon.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
input-error.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
mobile-back-button.tsx fix(haptics): use a local WebHaptics wrapper (#225) 2026-03-16 11:26:04 +00:00
nav-footer.tsx feat: Spanish localization (#74) 2026-02-08 11:58:08 +01:00
nav-main.tsx fix(haptics): use a local WebHaptics wrapper (#225) 2026-03-16 11:26:04 +00:00
nav-user.tsx feat(integration-requests): community board to request & vote bank integrations (#550) 2026-06-17 12:50:51 +00:00
pro-badge.tsx feat(mcp): read-only MCP server for Pro accounts (#689) 2026-07-17 16:54:15 +02:00
sortable-grid.test.tsx fix(accounts): stop second long-press haptic on drag handle (#578) 2026-06-22 11:20:57 +02:00
sortable-grid.tsx fix(accounts): stop second long-press haptic on drag handle (#578) 2026-06-22 11:20:57 +02:00
support-dialog.tsx feat(support): add support link with community-first help modal (#542) 2026-06-16 13:16:04 +02:00
text-link.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
two-factor-recovery-codes.tsx feat: Spanish localization (#74) 2026-02-08 11:58:08 +01:00
two-factor-setup-modal.tsx feat: Spanish localization (#74) 2026-02-08 11:58:08 +01:00
unlock-message-dialog.tsx feat(auth): show/hide toggle on password fields (#499) 2026-06-06 11:42:20 +02:00
user-info.tsx feat: Update facehash and enable blink 2026-02-24 15:54:49 +01:00
user-menu-content.test.tsx feat(feedback): move feedback and roadmap links from Canny to UserJot (#748) 2026-08-10 06:54:21 +00:00
user-menu-content.tsx feat(feedback): move feedback and roadmap links from Canny to UserJot (#748) 2026-08-10 06:54:21 +00:00