Feat/payments redesign 4 activity - #2193
arseniy-nikitochkin wants to merge 51 commits into
Conversation
…s and Schedules Moves the overview, Transactions (with a page per transaction and CSV export), Requests (with New request and a page per request), Schedules and the API playground layout to the refresh design. Every Payments route is now redesigned, so the per-route previous-design switch in the header and theme scope gives way to the NEW DESIGN flag alone. Files main has keep main's code at their paths. A redesigned file gets a .redesign sibling with the new version; a route's page.tsx or loading.tsx keeps main's code and picks its .redesign sibling on NEW DESIGN. With the flag off every page runs main's code. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s-redesign-4-activity # Conflicts: # apps/sdp-web/src/components/dashboard-header.tsx # apps/sdp-web/src/lib/theme-scope-routes.ts
…tivity flag The Payments overview and its API playground, Transactions, Requests and Schedules become the activity design module, a catch-all for the Payments routes Contacts and Pay & Deposit don't cover. Their routes, loading skeletons, theme scope, header and the Schedules sidebar label follow new-design-activity (SDP_FLAG_NEW_DESIGN_ACTIVITY, on by default), and only while NEW DESIGN is on. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s-redesign-4-activity
…mmand center e2e A project with no transfers shows the empty state, whose one way on is "Open Transactions"; "View all transactions" only follows a list with rows. CI's fresh project has none, so the assertion now accepts either link to Transactions inside the activity section. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The .redesign sibling differed from main's screen only in importing walletHref from the redesigned hrefs module, where it is the same function. React Doctor flagged the duplicated JSX; the ramp step contents and the test now use main's screen again, which leaves the ramp files exactly as PR #2169 has them. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
React Doctor flagged the run history's and the Requests list's header rows as one JSX tree written twice. PaymentsTableHeader renders the row from a column list in the design's 13px regular type, and both tables use it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The busy flag was cleared only on the error response, so a request that rejected left the Create button disabled for good (React Doctor: loading flag reset outside finally). The reset now runs in a finally block unless the link was made, when the page stays busy on its way to the request so a second press cannot make a second link. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…est by id The list loaded up to 500 requests on every visit, and listing reconciles each open request on chain, so a routine load could run hundreds of checks. The detail page looked only as far as that cap, so an older request's URL redirected to the list. The list now reads one page as the URL names it (page, size, status), with a "from-to of total" summary and a page past the end landing on the last; search runs over the loaded page. The detail lookup pages until it finds the request or the pages run out. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…acks it Changing the funding wallet kept the old token even when the new wallet did not hold it; the picker showed a placeholder but Save sent the pair, leaving a schedule that cannot collect. Switching wallets now keeps the token only if the new wallet offers it, Save asks for a token otherwise, and returning to the schedule's own wallet restores its token. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… e2e The Schedules row's link is its "<amount> to <contact>" title, not a bare amount, and the detail page is headed by that title with Pays/To/From/Repeats/Next run/Schedule ID lines in place of the legacy labels. The test timed out clicking the old amount text. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s-redesign-4-activity # Conflicts: # apps/sdp-web/src/app/dashboard/payments/payments-route-skeletons.redesign.tsx
…e Requests list Paging the Requests list on the server left search filtering only the loaded page, and the API's status filter reads the stored status, so a request paid since the last read was missed by Paid and shown as paid under Awaiting payment. Search now lives in the URL and the server reads up to 500 requests to match and page it, with a note when that cap is reached. Awaiting payment and Paid read the open requests first; listing settles any that has been paid, so the server's filter then matches the status the list shows. Other views keep one-page reads. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s-redesign-4-activity
…ps none Listing settles open requests as it reads them, so paging status=awaiting_payment moved every later offset up as earlier rows left the filter, and later pages skipped rows. The scan now reads all statuses newest first, whose order only a new request moves: repeated rows are dropped by id, and a grown total reads on. Awaiting payment and Paid are matched from that read; the 500 cap stays. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…eline The i18n guide forbids new baseline entries. Neither was copy: "allow" is the policy API's enum value and "activity" a design-module id, so they move into named constants and the baseline matches the base branch again. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s-redesign-4-activity
…arch A search under a status read only the newest 500 requests of every status, so a request within its status's newest 500 but outside that window was missed. Past the cap, a status search now also reads that status's newest requests by the API's filter (Paid reads the open ones too, which listing settles when paid), drops the rows already read, and keeps the unfiltered window first so its reconciled statuses still decide the match. The cap note shows only when a status read was itself capped. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…n finally The submit flag now always clears in finally, and a separate link-created flag keeps the form busy on its way to the request, so a second press still cannot make a second link. Tests cover the form staying busy after success and freeing when the request throws. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…eces Pull the URL builder, status filter menu, pager and row labels out of PaymentRequestsWorkspace to bring its complexity under React Doctor's limit. Behaviour is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s-redesign-4-activity Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ip no request Reading a page settles its paid requests, which leave the stored Awaiting payment set and pull every later row up a page. Read in parallel, a later page could then miss requests past the unfiltered read's cap. A one-row probe now reads the total, and the pages are read one at a time from the last to the first, so a request leaving only repeats a row already read. Paid, canceled and expired only gain requests, so their pages are read one at a time from the first. The unfiltered scan stays parallel. Repeated rows keep their first place and their freshest copy. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s-redesign-4-activity Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s-redesign-4-activity Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s-redesign-4-activity Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s-redesign-4-activity Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s-redesign-4-activity Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s-redesign-4-activity Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s-redesign-4-activity Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s-redesign-4-activity Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s-redesign-4-activity Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s-redesign-4-activity Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s-redesign-4-activity
… shared pieces Switch New schedule's Source wallet and amount/token row to SourceWalletField and AmountFields from ramps/components/payment-form-fields.tsx. Its hints, wallet total and decimal limit pass through as props and children; classes and DOM are unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s-redesign-4-activity Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…y request The API lists requests only by page and stored status, so a search could only cover the requests already read. The box is disabled and a search in the URL is ignored; the detail lookup notes that it pages through the list until the API reads a request by id. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Every page now comes from the API's own page, size and status. Under Awaiting payment, rows the API reconciles to paid are left out and the total drops by as many. The 500-request scan, its search matching and the "search covers the newest requests" note are removed. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s-redesign-4-activity Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s-redesign-4-activity Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…l other pages are read Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…nt without a count The search box is back on: a search lives in the URL, as before, and the list matches it against the page it has read, by amount, token, payer, destination and reference, carrying it along as the user pages on. Under Awaiting payment the API's total counts by stored status, so the pager names the page alone and offers the next while the API has one, instead of a count that could run high. Other statuses keep their exact range. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…sts-page.data.ts Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Measured against the design at 1536px: the balance label is 13px and the amount 6px under it; the token rows carry a 36px mark beside a 16px name over a 13px amount, 16px apart, with the USD value at 14px; the census sits 40px under them with 16px counts over 13px words; the Activity rows are 61px, ruled beneath, a 14px line over a 13px line with a 13px status, 12px from the heading row. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…s-redesign-4-activity Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…esign-4-activity Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… the mockup measures The transaction page's Provider and Proof headings sat 64px under the last row of the section above; the design draws 54. The 32px between blocks stays, the section's own top space drops from 32 to 22. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…s-redesign-4-activity Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…s-redesign-4-activity Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…s-redesign-4-activity
…nts-redesign-4-activity
|
React Doctor found no new issues. 🎉 Reviewed by React Doctor for commit |
|
|
|
||
| const changeWallet = (sourceCustodyWalletId: string) => { | ||
| const nextWallet = liveWallets.find((entry) => entry.id === sourceCustodyWalletId); | ||
| const nextOptions = recurringPaymentAssetOptions(nextWallet ?? null, {}, t); |
There was a problem hiding this comment.
Issued tokens disappear during editing
When an active schedule uses an issued token identified by its mint, this picker receives no issued-token symbols. Switching to another wallet that holds the same token can therefore clear the token selection and block Save changes, even though the wallet can fund the schedule. Pass the issued-token symbols already loaded by the detail route into the edit form.
Knowledge Base Used: Dashboard product workflows
| const result = await fetchPaymentRequests(request, { | ||
| page, | ||
| pageSize, | ||
| ...(status ? { status } : {}), | ||
| }); | ||
| const hasNextPage = result.ok && page * pageSize < result.total; |
There was a problem hiding this comment.
Pagination skips awaiting requests
If reading an Awaiting payment page reconciles a request as paid, that request leaves the status-filtered result set. The next page still uses the original offset and can skip an awaiting request. For example, with 26 requests and a page size of 25, one reconciled payment can leave the second page empty while the remaining request is never shown.
Knowledge Base Used: Dashboard product workflows
| const copyLink = (request: PaymentRequest) => { | ||
| void navigator.clipboard.writeText(`${window.location.origin}/pay/${request.publicToken}`); | ||
| toast.success(t("DashboardPayments.requests.paymentLinkCopied")); | ||
| }; |
There was a problem hiding this comment.
No description provided.