Skip to content

My Funding: a page built from what the user does - #1155

Merged
yattias merged 47 commits into
mainfrom
my-funding/redesign
Oct 8, 2026
Merged

yattias merged 47 commits into
mainfrom
my-funding/redesign

Conversation

@yattias

@yattias yattias commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

My Funding now builds itself from the user's own activity (what they funded, the RFPs they run, the proposals they wrote, their reviews) instead of asking who they are.

  • Hero in the Journal family: a headline from what the user gave, raised or runs, a fanned deck of their work (generic proposal and RFP cards when there is none), and one tab bar on every tab: Overview, Activity, then Funded, RFPs, Proposals and Reviews as they apply.
  • Overview: Up next (new proposals on an RFP, deadlines, funders waiting for an update; drafting an RFP or a proposal for someone new), Research you funded with the latest update or review on each, Your RFPs with budget committed, Your proposals, peer reviews, and Recent activity.
  • Right rail, the same for everyone: money in and out, people and institutions supported, your funders, and paid reviewing, with empty slots where there is nothing yet.
  • Activity: updates and peer reviews around the user's funding, with what is new since the last visit on top.
  • Signed out: a preview of the page instead of a redirect to home.
  • Loading: each state waits for its data behind a skeleton shaped like the page, so nothing shuffles in.
  • No API changes: same requests as before, plus two 2-item samples of open proposals and RFPs for new and signed-out visitors. Research you funded reads the funding overview only; RFP budget comes from the grant feed entry, and committed budget matches the RFP's proposals against the overview.
  • Removed: drafts carousel (drafts stay in the sidebar), summary card, activity rail, New RFP / New proposal buttons (the Publish menu starts those).

Stack

Stacked on #1154; merge that first, then this one.

🤖 Generated with Claude Code

@yattias
yattias added this pull request to stack #1146 October 8, 2026 13:47
@vercel

vercel Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
web Ready Ready Preview Oct 8, 2026 3:27pm UTC

Request Review

@yattias yattias changed the title My Funding builds itself from what the user does: a journal-style hero, Up next, funded research and a full sidebar My Funding: a page built from what the user does Oct 8, 2026
@yattias
yattias marked this pull request as ready for review October 8, 2026 13:47
@yattias
yattias requested a review from a team as a code owner October 8, 2026 13:47
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

yattias and others added 22 commits October 8, 2026 10:22
… body

The form's state and its publish flow now live in PublishingFormProvider
and usePublishAction, exposed through usePublishingController(), so a
publish button or a single section can render anywhere inside the
provider — the AI Mode workspace header needs both. PublishingForm keeps
only the sections and the footer. The pure note<->form mappings move to
formMapping.ts and are exported.

Both hosts (the notebook page and the AI Mode document pane) wrap the
form explicitly; readOnly moves onto the provider. One behaviour change:
publishing is refused while there is no editor, since it would otherwise
publish an empty work.

Verified with type-check, eslint and prettier only.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…sh controls

The document pane's Document / Publish tabs become a strip of detail
blocks — Applying to, Funding goal, Authors, Cover image for a proposal;
Funding amount, Short description, Contacts, Cover image for an RFP —
each opening a popover with just its section of the form (or, for the
RFP picker, the existing modal). The strip shows as many blocks as the
pane is wide enough for, in a fixed order, and folds the rest into the
"All details" block, which opens the full form and says how many it
holds (hooks/useFittingCount). The workspace header gains the document's
title, a "N remaining" pill and a Publish button that stays disabled
until nothing required is missing; a published document shows a
Published pill and an Update button. The form now lives as long as the
note does, so switching views no longer rehydrates it from stale content.

Below the tablet breakpoint the drawer trades the strip for a
Document | Details switch, with the remaining count on Details and the
publish controls inline.

Supporting changes: completion.ts derives what is missing from the zod
schema without touching form errors; PublishStatusPill; PublishButton
gains requireComplete and reads Update for published works; the funding
section is split into FundingOpportunityField, FundingGoalField and a
FundingGoalSection with a shared useSelectedGrant; sections take a
className so they render bare in a popover; PublishingForm gains
showFooter; NotebookTabs loses its labels prop and the header its
"Esc to close" hint.

Verified with type-check, eslint and prettier only.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…anel

useAIModeChat and AgentChatPanel each carried a copy of the same
machinery: create the chat on the first send, queue that first message
until the chat is live, keep a draft per chat across switches and failed
sends, wire model selection, tell the listing when a turn settles, and
word the composer's failure notices. hooks/useChatSession now holds it
once, keyed by `transport:chat`, and both surfaces sit on top of it;
components/AgentChat/chatNotices.ts holds the copy, with a policy for
what a surface calls a chat and who announces a spent budget.

Along the way: the queued first message is bound to the chat it was
queued for instead of firing on whichever chat is selected next; the
"new" draft no longer collides across scopes; the notebook composer now
clears on send and restores the text on failure, as the overlay always
did; and the overlay's composer takes the panel's fuller busy/stop
rules. Transports are handed out by getChatTransport so a scope always
gets the same object, and createChat takes a ChatCreateInit ready for
the fields a workspace conversation starts with.

Verified with type-check, eslint and prettier only.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ding

The new-conversation screen replaces its three starter cards with a
two-way toggle — I want to fund (blue, arrow out) / I need funding
(emerald, arrow in) — remembered per browser and defaulting to the
researcher's side. The choice goes to the backend with the conversation
as its intent, so the assistant drafts an RFP or a proposal without
guessing; the regex that inferred the work type from the opening message
is gone, along with the defaultArticleType seam it fed.

Under the composer a researcher gets two calls to action: connect their
researcher profile (ProfileEditModal narrowed to ORCID and Google
Scholar) and apply to a specific RFP (the existing selector; the choice
is sent with the conversation and lands on the proposal it creates). A
funder gets one line to talk to the ResearchHub team.

Shared pieces: components/Funding/fundingDirection.ts and
FundingDirectionIcon carry the arrow-and-colour language, which the
My Funding tabs now use too; ButtonGroup options take an
activeClassName; ProfileInformationForm can show a subset of its social
links.

Verified with type-check, eslint and prettier only.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
useOrganizationNotes holds what NotebookContext did for the notes list:
the plain listing and the Registered Reports fetched alongside, merged,
and paged as two independent streams. The context now consumes it, with
no change in behaviour, so a surface that is not the notebook page — the
AI Mode workspace's sidebar — can list the same notes.

types/note.ts gains isProposalNote and getNoteKind, which reads a note
as a proposal, an RFP, a Registered Report, a preprint or untyped from
the same signals isRfpNote already used. The editor's work-type label is
now looked up from that kind instead of its own switch.

Verified with type-check, eslint and prettier only.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
AIModeOverlay.tsx is composition only now. What it did itself moves to
named modules: shell/useModalOverlayBehavior (focus, inert siblings,
scroll lock, Esc), shell/AIModeHeader, and shell/WorkspacePanes, which
lays out sidebar, chat and document. The chat and the document keep
fixed places in the tree and swap on screen with flex order, so the
layout can change without remounting the editor or the transcript.

The sidebar is its own set of pieces — WorkspaceSidebar, a
ConversationsSection that shows the most recent conversations and a
"Show all" for the rest, and a SidebarRow and SidebarGroupHeading the
documents section will share. The rest of the folder is grouped by
concern: chat/, document/, start/, sidebar/, shell/.

Verified with type-check, eslint and prettier only.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…e used

The workspace's URL now names a target: a conversation (?aiChat) or a
document (?aiNote, with ?aiChat for the chat on it) and which pane is
the main one (?aiView=doc). Clicking a conversation opens chat-first;
clicking a document from the sidebar's new Documents section opens it
document-first with a fresh chat beside it, scoped to that note through
the notebook's own chat transport. A header toggle swaps the layout for
the current target; the panes keep their places in the tree and trade
places on screen.

A document's chat is created on its first message, like any other, and
from then on it is listed under Conversations — the assistant listing
now includes notebook chats — and reopens on its document. Rows route
renames and deletes to the surface that serves them, and a chat on a
document never offers to delete the document. The sidebar's Documents
section lists the organization's notes with each one's kind marked by
the money's direction, refetching when the open conversation creates
one.

Verified with type-check, eslint and prettier only.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Below the tablet breakpoint the sidebar no longer peeks up as a bottom
drawer. A PanelLeft button in the chat header — the same icon the
desktop's column suggests — opens the sidebar as a screen of its own,
with a header that closes it, so the Documents section has the room its
rows need.

Verified with type-check, eslint and prettier only.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…otebook link

- The All details block no longer wraps: its width allows for the label,
  the folded count and the tally on one line each, and no block label
  wraps any more.
- The Chat first / Document first toggle is gone. A document opened from
  the sidebar is always document first; a conversation is chat first.
  The ?aiView parameter goes with it.
- "Open in notebook" is gone from the document pane: the workspace is
  meant to replace the notebook, not lead back to it.
- Sidebar rows show their title only — no timestamp, kind or status
  under it — in both groupings.

Verified with type-check, eslint and prettier only.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The Notebook nav item becomes Workspace, with a briefcase, and a matching
button sits in the top bar beside the user controls; both open the
new-conversation screen. The header gets a back arrow in place of the
close button and shows what is open: the conversation when the chat is
the main pane, the document when it is. A document target remembers how
it was reached (`aiView=chat` for a conversation), so a chat opened from
the list keeps its chat-first layout. The detail-block strip is now one
joined bar with no gaps or dashed borders.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The new-conversation screen loses its logo and its title. The fund /
need-funding choice is a pair of tabs on the composer's top edge; the
open tab merges into the box and the box takes its colour, and the send
button goes emerald for a researcher. The researcher's profile and the
RFP they are answering ride in the composer's toolbar as chips: a plug
until connected, then the connected services' logos ("Scholar, ORCID");
"Apply to RFP" until chosen, then the RFP with an × to remove it. The
model and effort controls sit under the box at its right, without
icons, in every workspace composer.

Around it: the chat pane shows no title while the chat is the main pane
(the top strip names it); the Workspace name in the strip is larger and
black; the nav item moves under My Funding with a New badge; the detail
block strip runs edge to edge with an even inset outline on the open
block; the RFP picker keeps one width while loading and is titled
"Select RFP to apply to"; the profile modal explains what connecting
does and drops its section heading.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The funder hero and earnings summary become one totals card above the
gray rail, recent activity moves into the rail as a vertical list shared
with the RFP page, and the workspace composer sits under the tabs with
the tab as its intent. The horizontal author-posts carousel goes away.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The Workspace nav item, the top-bar briefcase and the phone-nav slot go
away. A Publish menu item or the New RFP / New proposal button on My
Funding opens the workspace for that side of the money, so the start
screen no longer asks with intent tabs; users the workspace does not
admit keep the notebook path.

My Funding drops the page composer and lists drafts ahead of published
work in both sections, each under a status line: blue dot published,
amber dot draft. The workspace sidebar's Documents become Drafts, with a
plain document icon carrying the same dot.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The top strip drops the briefcase and the Workspace label: just the way
back and the title, with the new-conversation screen titled as such, the
way a selected conversation is. Under a funder's composer the team link
becomes a concierge card with the PhD's avatar: book a call to discuss
the funding opportunity.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
On My Funding a draft's amber dot and last-edited time sit inside its
row under the title, instead of on a line above it, and a section shows
four drafts before asking to expand. In the workspace's journey rail the
connector runs from dot to dot rather than stopping short.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Published RFPs and proposals join the drafts as rows, not feed cards:
title, then the status dot and a date, a draft dashed and a published
one solid. The section's empty state only shows when there is nothing
at all, drafts included, which it wrongly did before. Four rows show
before the list asks to expand, then the feed's next page on demand.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
An RFP still open or a proposal still raising leads its section, then
the drafts, then what has closed, with the state named on a closed row.
A published row shows the document's image in place of the file icon
and, at its right, an RFP's funding or a proposal's raised amount and
goal, in the user's currency.

The activity rail's Author badge was cut off beside a long name: the
actor line truncated as a whole and the name never gave way. The name
now truncates and the badge stays whole.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The start screen's composer takes focus the moment the workspace opens
on it, from the Publish menu, a My Funding button or the sidebar; the
overlay root only takes focus when nothing inside has it.

The document pane kept the full details form mounted, hidden, behind
the document while a detail block's popover showed the same field. Two
inputs on one name left the form reading and writing through whichever
attached last, so keystrokes in the popover could be read from, or
overwritten by, the hidden copy. The form now mounts only while the
details view shows; its values live in the provider either way.

The funder totals' institutions row shows a building icon with the
count instead of name chips.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The confirm-publish dialog's RFP guidelines are the three the team
settled on: only create an RFP if you mean to distribute the amount,
describe scope and expectations clearly, stick to truth-seeking
science.

Publishing from the workspace used to leave the overlay on screen,
saying "Redirecting…", until the work's page had loaded behind it. The
publishing host now takes an onPublished hook, and the workspace closes
itself through it the moment the publish succeeds, so the page is what
the user watches arrive.

On My Funding a draft row carries a delete control, behind a
confirmation, and a section's rows render only once both its drafts
and its published work have loaded, instead of laying out twice.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The trash button beside a draft row becomes an ellipsis menu with a
Delete item, the same control a conversation row has in the workspace.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The journey rail's steps drop their icons on both sides, and the funder
dashboard card keeps only its arrow. The proposal side's "stay in
control" note leaves the rail for a line under the composer: you
control who sees your proposal, public or private to funder. On My
Funding the section is "My RFPs".

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The proposal side's privacy line becomes a card in the concierge card's
shape, with a lock: you control who sees your proposal. The start
screen's heading is "Let's get started" instead of a greeting by name,
and the timeline copy is tightened.

On an RFP page with a funding pool, the tabs no longer take a row of
their own beneath both columns, which left the title's column empty
down to the pool's foot. The hero header can keep its tabs in the
title's column beside the CTA, and the RFP header does so, so the tabs
sit level with the pool's footnote and the hero is that much shorter.

The Publish menu and the homepage's RFPs and Proposals tabs use the
funding-direction arrows My Funding uses for the same two sides.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
yattias and others added 20 commits October 8, 2026 10:27
The top strip's title and the sidebar's button name what the next
conversation makes, for the side of the money the user came in on,
instead of "New conversation".

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
playwright-report, test-results and blob-report join the global
ignores, so a smoke run's leftovers are not linted.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The RFP page's "Updates" tab is now "Activity", with the radiating dot
in place of the bell. The Recent Activity rail's heading carries the
same dot, so SidebarHeader takes a node for its title. The rail can
also say its data failed to load instead of reading as empty.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The Funds given / Funds received tabs go. The page no longer asks which
side of funding its user is on: a hero names the page and holds New RFP
and New proposal, and under it are two tabs.

Overview leads with the numbers as two cards, funds given and funds
received, each opening its detail below the pair. Then what the user
has written: drafts as a carousel to pick back up from, published RFPs
and proposals in one list with active work first, and their peer
reviews as compact rows. Activity is the full feed of what applicants
and reviewers have been up to, merged with the user's own updates and
reviews; the same stream fills the rail beside the column.

A moderator's "view as" control moves into the tab bar and reads only
that funder's giving side. The feed and overview hooks now return their
error, so the page says when data failed to load instead of looking
empty. The RFP and proposal icons live in one place, fundingKind, which
the Publish menu reads too.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Conversations and drafts take the nav's place in the left column, and
the chat and document fill the rest. Old ?ai=1 links redirect.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…dialog

The detail blocks and the workspace strip are gone. The open title sits
in the app's top bar; under the note's title one quiet line carries the
authors, the funding goal, the RFP and an offer for anything unset.
Nothing on the document marks a detail as missing: Publish opens a
dialog that lists what is still empty, takes it there, holds the
settings, and publishes under the note's title.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…istory

Drafts and Published list the user's RFPs and proposals under the nav on
every page, loaded once in a provider that My Funding's drafts read too.
The workspace keeps the app's sidebar, with the chat on the left and the
document on the right. A document opens on its most recent chat; History
switches between its chats or starts a new one, and the chat's menu
renames or deletes it. A new draft's first message creates the note,
then a chat on it. A dot shows the assistant at work on the document,
whose details are fetched again once a turn settles. Every signed-in
user drafts here, and the old ?ai= links are gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A sent message now counts as the assistant working from the moment it
leaves: while its chat is being created, while it waits for that chat to
open, and while it is posted. An empty document shows "Starting the
document" from then on, even before the note has loaded, instead of
flashing a skeleton and the empty page until the turn shows up. It stays
until the draft starts streaming in; a turn that writes nothing leaves
the empty document.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… publish dialog fixes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The homepage rail's Recently visited rows now carry a 48px picture on the
right and the time of the visit above a two-line title, with no document
type. A row's picture is the cover image (or a paper's first PDF page),
else a drawn title page for papers, else the first author's photo, else
the file icon from My Funding. The list stops at six rows so it fits under
the funding power card on a 900px-tall window; the single Clear stays.

Visits now record the picture, an author photo and the visit time.
Entries saved before this show the file icon and no time until revisited.
A paper and a post with the same id no longer evict each other.

Everything lives in components/RecentlyVisited; FundSidebar, which only
ever showed this list, is now RecentlyVisited.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The left sidebar's footer (social icons, the currency select and six text
links) becomes a single row, 53px instead of 143px, so the nav and the
Drafts / Published lists keep that height. The row opens a menu upward
with What's new (tagged New until the changelog is opened; the orange dot
moves onto the row), Docs, Support and About, a USD / RSC switch that
keeps the menu open, and the social icons beside Terms and Privacy.
External links open in a new tab.

The changelog's seen state moves into useChangelogSeen, shared with
ChangelogLink (still used by the phone's More drawer). BaseMenu takes an
optional side so a menu can open above its trigger. FooterLinks is gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lish drawer, workspace nav

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ails

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… nonprofit

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d the editorial board

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…o, Up next, funded research and a full sidebar

- Hero in the Journal family: a headline from what the user gave, raised or runs, a fanned deck of their work (generic proposal and RFP cards when there is none), and one tab bar for every tab: Overview, Activity, then Funded, RFPs, Proposals and Reviews as they apply.
- Overview: Up next (new proposals on an RFP, deadlines, funders waiting for an update; drafting an RFP or a proposal for someone new), Research you funded, Your RFPs with budget committed, Your proposals, peer reviews, and Recent activity.
- Research you funded comes from the funding overview alone, with the latest update or review on each proposal.
- The right rail is the same for everyone: money in and out, people and institutions supported, your funders, and paid reviewing, with empty slots where there is nothing yet.
- Activity: updates and peer reviews around the user's funding, with what is new since the last visit on top.
- Signed-out visitors get a preview instead of a redirect; every state waits for its data behind a skeleton the shape of the page.
- No new endpoints: the page uses the same requests as before, plus two small samples of open proposals and RFPs for new and signed-out visitors.
- Drafts carousel, summary card and activity rail removed; drafts stay in the sidebar.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Journal and Peer Review: less padding (48px on desktop, 40px on phones), the card stack at its phone size so it no longer sets the height, and hidden below lg like My Funding's deck. About 450px down to 350px on desktop.
- Peer Review's three-step timeline fits a phone without scrolling sideways.
- My Funding's signed-in and welcome heroes take the same padding and are held to the same 350px from lg, with one deck size; shorter lines for signed-out and brand-new visitors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@yattias
yattias force-pushed the my-funding/redesign branch from fddb27a to b47ef5a Compare October 8, 2026 14:46
@yattias
yattias removed this pull request from stack #1146 October 8, 2026 15:07
Journal, Peer Review and My Funding: compact heroes of one height
@sonarqubecloud

sonarqubecloud Bot commented Oct 8, 2026

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@yattias
yattias changed the base branch from peer-review/journal-hero to main October 8, 2026 15:28
@yattias
yattias merged commit 719edba into main Oct 8, 2026
4 of 5 checks passed
@yattias
yattias deleted the my-funding/redesign branch October 8, 2026 15:29

This branch was successfully deployed

1 active deployment
Preview — 059fcdf7 Deployed Oct 8, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant