-
Notifications
You must be signed in to change notification settings - Fork 484
payouts tab #1065
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
payouts tab #1065
Conversation
Preview Screenshots⏳ Preview screenshots are being captured... Workspace and dev browser links will appear here once the preview environment is ready. Generated by cmux preview system |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughThe pull request adds a new Payouts feature to the payments dashboard. Changes include configuring Stripe account session with payouts components, creating new payouts page components, adding a navigation item to the payments app, and updating import paths for module resolution. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings, 1 inconclusive)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile OverviewGreptile SummaryAdded payouts management tab to the payments dashboard that displays Stripe's embedded payouts widget for viewing and managing payment disbursements. Key Changes
Issues Found
Confidence Score: 4/5
Important Files ChangedFile Analysis
Sequence DiagramsequenceDiagram
participant User as User/Browser
participant Page as Payouts Page
participant Provider as StripeConnectProvider
participant AdminApp as StackAdminApp
participant API as Backend API
participant Stripe as Stripe API
participant Widget as ConnectPayouts Widget
User->>Page: Navigate to /payments/payouts
Page->>Provider: Render with StripeConnectProvider
Provider->>AdminApp: getStripeConnectInstance()
Provider->>API: createStripeWidgetAccountSession()
API->>Stripe: accountSessions.create()
Note over API,Stripe: Components: payments, notification_banner, payouts
Stripe-->>API: Return client_secret
API-->>Provider: Return client_secret
Provider->>Stripe: loadConnectAndInitialize(client_secret)
Stripe-->>Provider: ConnectInstance
Provider->>Widget: Render ConnectPayouts
Widget->>Stripe: Fetch payout data
Stripe-->>Widget: Return payout information
Widget-->>User: Display payouts interface
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
5 files reviewed, 1 comment
| @@ -0,0 +1,9 @@ | |||
| "use client"; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: remove this directive - page.tsx should be a server component
other payment pages like customers/page.tsx and products/page.tsx don't have this directive
| "use client"; | |
| import PageClient from "./page-client"; |
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/page.tsx
Line: 1:1
Comment:
**style:** remove this directive - `page.tsx` should be a server component
other payment pages like `customers/page.tsx` and `products/page.tsx` don't have this directive
```suggestion
import PageClient from "./page-client";
```
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/page.tsx (1)
1-9: Drop"use client"here; keeppage.tsxas a server wrapper like the other Payments pages.
This avoids widening the client boundary for the entire route when the wrapper itself has no client-only logic.-"use client"; - import PageClient from "./page-client"; export default function Page() { return ( <PageClient /> ); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
apps/backend/src/app/api/latest/internal/payments/stripe-widgets/account-session/route.ts(1 hunks)apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/layout.tsx(1 hunks)apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/page-client.tsx(1 hunks)apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/page.tsx(1 hunks)apps/dashboard/src/lib/apps-frontend.tsx(1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Always add new E2E tests when changing the API or SDK interface
For blocking alerts and errors, never use toast; use alerts instead as they are less easily missed by the user
NEVER try-catch-all, NEVER void a promise, and NEVER .catch(console.error); use loading indicators and async callbacks instead, or use runAsynchronously/runAsynchronouslyWithAlert for error handling
Use ES6 maps instead of records wherever you can
Files:
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/page-client.tsxapps/backend/src/app/api/latest/internal/payments/stripe-widgets/account-session/route.tsapps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/layout.tsxapps/dashboard/src/lib/apps-frontend.tsxapps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/page.tsx
**/*.{ts,tsx,css}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,css}: Keep hover/click transitions snappy and fast; avoid fade-in delays on hover. Apply transitions after action completion instead, like smooth fade-out when hover ends
Use hover-exit transitions instead of hover-enter transitions; for example, use 'transition-colors hover:transition-none' instead of fade-in on hover
Files:
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/page-client.tsxapps/backend/src/app/api/latest/internal/payments/stripe-widgets/account-session/route.tsapps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/layout.tsxapps/dashboard/src/lib/apps-frontend.tsxapps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/page.tsx
apps/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
NEVER use Next.js dynamic functions if you can avoid them; prefer using client components and hooks like usePathname instead of await params to keep pages static
Files:
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/page-client.tsxapps/backend/src/app/api/latest/internal/payments/stripe-widgets/account-session/route.tsapps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/layout.tsxapps/dashboard/src/lib/apps-frontend.tsxapps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/page.tsx
{.env*,**/*.{ts,tsx,js}}
📄 CodeRabbit inference engine (AGENTS.md)
Prefix environment variables with STACK_ (or NEXT_PUBLIC_STACK_ if public) so changes are picked up by Turborepo and improves readability
Files:
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/page-client.tsxapps/backend/src/app/api/latest/internal/payments/stripe-widgets/account-session/route.tsapps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/layout.tsxapps/dashboard/src/lib/apps-frontend.tsxapps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/page.tsx
apps/dashboard/**/*
📄 CodeRabbit inference engine (AGENTS.md)
When making changes in the dashboard, provide the user with a deep link to the dashboard page changed, usually in the form of http://localhost:<NEXT_PUBLIC_STACK_PORT_PREFIX>01/projects/-selector-/... or using a.localhost, b.localhost, c.localhost for port prefixes 91, 92, 93
Files:
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/page-client.tsxapps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/layout.tsxapps/dashboard/src/lib/apps-frontend.tsxapps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/page.tsx
apps/**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
Check existing apps for inspiration when implementing new apps or pages; update apps-frontend.tsx and apps-config.ts to add new apps
Files:
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/page-client.tsxapps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/layout.tsxapps/dashboard/src/lib/apps-frontend.tsxapps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/page.tsx
🧠 Learnings (2)
📚 Learning: 2025-12-04T18:03:49.984Z
Learnt from: CR
Repo: stack-auth/stack-auth PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-04T18:03:49.984Z
Learning: Applies to apps/**/*.tsx : Check existing apps for inspiration when implementing new apps or pages; update apps-frontend.tsx and apps-config.ts to add new apps
Applied to files:
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/layout.tsxapps/dashboard/src/lib/apps-frontend.tsx
📚 Learning: 2025-12-04T18:03:49.984Z
Learnt from: CR
Repo: stack-auth/stack-auth PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-04T18:03:49.984Z
Learning: Applies to apps/**/*.{ts,tsx} : NEVER use Next.js dynamic functions if you can avoid them; prefer using client components and hooks like usePathname instead of await params to keep pages static
Applied to files:
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/page.tsx
🧬 Code graph analysis (2)
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/page-client.tsx (1)
apps/dashboard/src/components/payments/stripe-connect-provider.tsx (1)
StripeConnectProvider(33-52)
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/page.tsx (3)
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/page-client.tsx (1)
PageClient(7-16)apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/transactions/page.tsx (1)
Page(3-5)apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/customers/page.tsx (1)
Page(7-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
- GitHub Check: Vercel Agent Review
- GitHub Check: build (22.x)
- GitHub Check: restart-dev-and-test-with-custom-base-port
- GitHub Check: docker
- GitHub Check: build (22.x)
- GitHub Check: lint_and_build (latest)
- GitHub Check: E2E Tests (Node 22.x, Freestyle prod)
- GitHub Check: E2E Tests (Node 22.x, Freestyle mock)
- GitHub Check: all-good
- GitHub Check: check_prisma_migrations (22.x)
- GitHub Check: restart-dev-and-test
- GitHub Check: setup-tests
🔇 Additional comments (3)
apps/dashboard/src/lib/apps-frontend.tsx (1)
138-143: Navigation entry is consistent with existing Payments items (./...) and should route correctly.apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/layout.tsx (1)
14-15: Import paths resolve correctly; no action needed.Both imports reference existing files with the correct exports:
../app-enabled-guard→AppEnabledGuardfunction (line 11 of app-enabled-guard.tsx) ✓../use-admin-app→useAdminAppfunction (line 29 of use-admin-app.tsx) ✓apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/page-client.tsx (1)
1-16: Code follows Stripe's documented pattern forConnectPayouts.The
ConnectPayoutscomponent is correctly used without props and is properly nested withinStripeConnectProvider, which handles the requiredConnectInstanceinitialization. No modifications needed.
| import { StripeConnectProvider } from "@/components/payments/stripe-connect-provider"; | ||
|
|
||
| export default function PageClient() { | ||
|
|
||
| return ( | ||
| <PageLayout title="Payouts"> | ||
| <StripeConnectProvider> | ||
| <ConnectPayouts /> | ||
| </StripeConnectProvider> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| import { StripeConnectProvider } from "@/components/payments/stripe-connect-provider"; | |
| export default function PageClient() { | |
| return ( | |
| <PageLayout title="Payouts"> | |
| <StripeConnectProvider> | |
| <ConnectPayouts /> | |
| </StripeConnectProvider> | |
| export default function PageClient() { | |
| return ( | |
| <PageLayout title="Payouts"> | |
| <ConnectPayouts /> |
Remove the redundant <StripeConnectProvider> wrapper around <ConnectPayouts />. The provider is already supplied by the parent layout, making this unnecessary nesting inconsistent with other payment pages.
View Details
Analysis
Redundant StripeConnectProvider wrapper in payouts page
What fails: apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/page-client.tsx unnecessarily wraps <ConnectPayouts /> with <StripeConnectProvider>, creating redundant nesting of the same React Context provider that is already supplied by the parent layout.
How to reproduce:
// apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/page-client.tsx
<PageLayout title="Payouts">
<StripeConnectProvider> {/* Redundant - already provided by parent layout */}
<ConnectPayouts />
</StripeConnectProvider>
</PageLayout>Result: Unnecessary component nesting. The ConnectPayouts component is wrapped by two instances of StripeConnectProvider - one from the layout and one from page-client.
Expected: Following Stripe's guidance to "Create a single connect instance...Then reuse that instance to create and manage multiple components", the component should be rendered directly within the existing provider context from the parent layout, matching the pattern used by other payment pages (customers, products, transactions).
Why this is a bug:
- Layout provides
<StripeConnectProvider>wrapping all payment pages (line 82) - Other payment page-client files (customers, products, transactions) do NOT wrap components with StripeConnectProvider
ConnectNotificationBannerin the same layout works fine within the parent provider without additional wrapping- React Context providers don't need to be nested - the inner provider is unused
| "use client"; | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| "use client"; |
Remove the unnecessary "use client" directive from page.tsx. This file is a server component that just renders the client component and shouldn't have the directive. All other similar pages follow this pattern correctly.
View Details
Analysis
Unnecessary "use client" directive on server wrapper component
What fails: The page.tsx file in apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/ incorrectly has the "use client" directive. This file is a Server Component that only renders the PageClient component and contains no interactive features, state, or browser APIs that would require client-side rendering.
How to reproduce:
- Examine apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/payouts/page.tsx
- Compare with equivalent pages: customers/page.tsx, products/page.tsx, and transactions/page.tsx
- All similar pages follow the pattern of NOT having "use client" on the server wrapper (page.tsx), only on the client component (page-client.tsx)
Result: The payouts/page.tsx incorrectly declares itself as a client component despite being a pure wrapper with no client-side requirements.
Expected: According to Next.js Server and Client Components documentation, the "use client" directive should only be added to components requiring interactivity. Server Components should remain unmarked by default. The file should follow the established codebase pattern of omitting "use client" on server wrapper components, just like customers/page.tsx, products/page.tsx, and transactions/page.tsx.
Implementation: Removed the "use client" directive from the top of the file, maintaining the wrapper pattern consistent with other similar pages in the codebase.
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.