Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughReworked per-team projects layout and moved the TeamAddUserDialog trigger beside each team label; dialog now fetches Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant ProjectsPage
participant Dialog as TeamAddUserDialog
participant API as listUsers / getItem
participant Billing as Checkout
participant Toast as UI_Toast
User->>ProjectsPage: View projects grouped by computed team label
ProjectsPage->>Dialog: Render trigger beside team label
User->>Dialog: Open dialog and submit invite
rect rgba(220,235,255,0.35)
Dialog->>API: listUsers(teamId)
Dialog->>API: getItem("dashboard_admins")
API-->>Dialog: users, admins.quantity
alt admins.quantity reached
Dialog->>Billing: create checkout URL
Billing-->>Dialog: checkout URL
Dialog->>User: Redirect to checkout
else under limit
Dialog->>API: send invite / add teammate
API-->>Dialog: success
Dialog->>Toast: show success message
end
end
note right of Dialog: Validation uses fetched `admins.quantity` during submit
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used📓 Path-based instructions (3){apps/dashboard,apps/dev-launchpad,packages/stack-ui,packages/react}/**/*.{tsx,jsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*.{ts,tsx,js,jsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
{apps/dashboard,apps/dev-launchpad,packages/stack-ui,packages/react}/**/*.{tsx,jsx,css}📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧬 Code graph analysis (1)apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/page-client.tsx (1)
⏰ 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). (11)
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 |
There was a problem hiding this comment.
Greptile Overview
Summary
This PR significantly improves the user experience of the team member invitation feature in the dashboard. The changes focus on making the invite functionality more discoverable and accessible by restructuring the layout and improving visual hierarchy.The core change involves moving the invite button from being embedded within the team name label (as a small icon-only button) to a dedicated position on the right side of the team header. The new layout uses a flex container with justify-between to clearly separate the team name on the left from the invite action on the right. The button itself has been enhanced from a minimal icon-only design to a more prominent button that includes both a UserPlus icon and descriptive text ("Invite Teammate"), making its purpose immediately clear to users.
The PR also includes important backend improvements to the validation logic. The previous implementation used reactive hooks to check user counts, but this has been refactored to use async API calls (Promise.all with listUsers() and getItem("dashboard_admins")) for more precise control over when validation occurs. This change likely addresses potential race conditions or stale data issues during the validation process.
Additionally, the dialog title has been improved to show the team name dynamically, and the Suspense wrapper around the dialog component has been removed, simplifying the loading state management. These changes integrate well with the existing codebase structure, maintaining the same core functionality while significantly enhancing discoverability and user experience.
Important Files Changed
Changed Files
| Filename | Score | Overview |
|---|---|---|
| apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/page-client.tsx | 4/5 | Improved team member invitation UX by moving invite button to prominent position with descriptive text and refactored validation logic to use async API calls |
Confidence score: 4/5
- This PR is safe to merge with minimal risk as it primarily improves UI/UX without breaking existing functionality
- Score reflects well-structured changes that enhance user experience while maintaining proper validation logic
- Pay close attention to the validation logic refactoring to ensure async API calls work correctly in all scenarios
Sequence Diagram
sequenceDiagram
participant User
participant PageClient
participant TeamAddUserDialog
participant FormDialog
participant Team
participant Router
User->>PageClient: "Load projects page"
PageClient->>PageClient: "Filter and sort projects by team"
PageClient->>User: "Display projects grouped by team with invite buttons"
User->>TeamAddUserDialog: "Click 'Invite Teammate' button"
TeamAddUserDialog->>FormDialog: "Open invite dialog"
FormDialog->>User: "Show email input form"
User->>FormDialog: "Enter email and submit"
FormDialog->>TeamAddUserDialog: "Trigger onSubmit with email"
TeamAddUserDialog->>Team: "listUsers()"
Team->>TeamAddUserDialog: "Return user list"
TeamAddUserDialog->>Team: "getItem('dashboard_admins')"
Team->>TeamAddUserDialog: "Return admin quota"
alt User limit reached
TeamAddUserDialog->>User: "Show quota limit alert"
TeamAddUserDialog->>Team: "createCheckoutUrl()"
Team->>TeamAddUserDialog: "Return checkout URL"
TeamAddUserDialog->>Router: "Redirect to checkout"
else User limit not reached
TeamAddUserDialog->>PageClient: "Call props.inviteUser()"
PageClient->>PageClient: "Execute invite user function"
PageClient->>TeamAddUserDialog: "Return success"
TeamAddUserDialog->>User: "Show success toast"
TeamAddUserDialog->>FormDialog: "Close dialog"
end
1 file reviewed, 1 comment
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/page-client.tsx
Show resolved
Hide resolved
There was a problem hiding this comment.
Review by RecurseML
🔍 Review performed on 017b43f..fc3e92c
| Severity | Location | Issue | Delete |
|---|---|---|---|
| apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/page-client.tsx:150 | Incorrect displayName rendering |
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/page-client.tsx
Show resolved
Hide resolved
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/page-client.tsx
Outdated
Show resolved
Hide resolved
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/page-client.tsx
Show resolved
Hide resolved
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/page-client.tsx
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/page-client.tsx (1)
105-109: Inline the computed team instance once.We call
teams.find(...)inside the conditional and again when passing the prop, so we walk the array twice on every render. Hoist the result into aconst team = ...and reuse it to keep the render path clean.Apply this diff:
- {teamId && teams.find(t => t.id === teamId) && ( - <TeamAddUserDialog - team={teams.find(t => t.id === teamId)!} + {teamId && (() => { + const team = teams.find((t) => t.id === teamId); + if (!team) return null; + return ( + <TeamAddUserDialog + team={team} onSubmit={(email) => props.inviteUser(window.location.origin, teamId, email)} - /> - )} + /> + ); + })()}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/page-client.tsx(3 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
{apps/dashboard,apps/dev-launchpad,packages/stack-ui,packages/react}/**/*.{tsx,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
For blocking alerts and errors in UI, do not use toast notifications; use alerts instead
Files:
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/page-client.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Prefer ES6 Map over Record when representing key–value collections
Files:
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/page-client.tsx
{apps/dashboard,apps/dev-launchpad,packages/stack-ui,packages/react}/**/*.{tsx,jsx,css}
📄 CodeRabbit inference engine (AGENTS.md)
Keep hover/click animations snappy; avoid pre-transition delays on hover and apply transitions after the action (e.g., fade-out on hover end)
Files:
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/page-client.tsx
⏰ 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). (10)
- GitHub Check: Vercel Agent Review
- GitHub Check: build (22.x)
- GitHub Check: build (22.x)
- GitHub Check: docker
- GitHub Check: setup-tests
- GitHub Check: restart-dev-and-test
- GitHub Check: all-good
- GitHub Check: docker
- GitHub Check: lint_and_build (latest)
- GitHub Check: Security Check
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/page-client.tsx
Show resolved
Hide resolved
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/page-client.tsx
Show resolved
Hide resolved
N2D4
left a comment
There was a problem hiding this comment.
can we instead have a gear button (eg. SettingsIconButton) to the right side of the team name? the button is too big imo
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/page-client.tsx
Outdated
Show resolved
Hide resolved
<img width="1458" height="968" alt="Screenshot 2025-10-10 at 2 27 00 PM" src="https://github.com/user-attachments/assets/ad2a4ecb-35b8-4b8b-a553-899ce0096d7a" /> (PAST) <img width="1483" height="608" alt="Screenshot 2025-10-07 at 1 54 00 PM" src="https://github.com/user-attachments/assets/abb854ba-fd9b-41de-a755-432262c8e1b2" /> <!-- Make sure you've read the CONTRIBUTING.md guidelines: https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md --> <!-- RECURSEML_SUMMARY:START --> ## High-level PR Summary This PR improves the visibility and usability of the team member invitation feature by replacing a small icon button with a more prominent button labeled "Invite Teammate", reorganizing the team header layout to better position the invite button, and making the invite functionality more robust by fetching user and admin data asynchronously instead of using hooks. ⏱️ Estimated Review Time: 5-15 minutes <details> <summary>💡 Review Order Suggestion</summary> | Order | File Path | |-------|-----------| | 1 | `apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/page-client.tsx` | </details> [](https://discord.gg/n3SsVDAW6U) [](https://squash-322339097191.europe-west3.run.app/interactive/c4a12ca45690d2b2efe881942a7d9c195dff13ea7131f2b33fa1377eb7b3cbb8/?repo_owner=stack-auth&repo_name=stack-auth&pr_number=932) <!-- RECURSEML_SUMMARY:END --> <!-- ELLIPSIS_HIDDEN --> ---- > [!IMPORTANT] > Enhances team member invitation UI and refactors data fetching in `page-client.tsx` for better usability and robustness. > > - **UI Enhancements**: > - Replaced icon-only invite button with a ghost button labeled "Invite Teammate" in `page-client.tsx`. > - Reorganized team header layout to better position the invite button. > - **Data Fetching**: > - Updated `TeamAddUserDialog` to fetch user and admin data asynchronously instead of using hooks. > - Validates admin limits at submission time in `TeamAddUserDialog`. > - **Misc**: > - Dialog title now reflects the team's display name in `TeamAddUserDialog`. > > <sup>This description was created by </sup>[<img alt="Ellipsis" src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=stack-auth%2Fstack-auth&utm_source=github&utm_medium=referral)<sup> for 3e16f0c. You can [customize](https://app.ellipsis.dev/stack-auth/settings/summaries) this summary. It will automatically update as commits are pushed.</sup> ---- <!-- ELLIPSIS_HIDDEN --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Projects are now grouped by team with readable team labels and a “No Team” fallback; each team shows its own project grid. * The “Add User” dialog is available next to each team and shows the team’s display name in the title. * **Style** * Replaced icon-only trigger with a ghost button using a settings icon and improved accessibility. * **Chores** * Invite submission now validates current admin limits at submit time. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Konsti Wohlwend <n2d4xc@gmail.com>
High-level PR Summary
This PR improves the visibility and usability of the team member invitation feature by replacing a small icon button with a more prominent button labeled "Invite Teammate", reorganizing the team header layout to better position the invite button, and making the invite functionality more robust by fetching user and admin data asynchronously instead of using hooks.
⏱️ Estimated Review Time: 5-15 minutes
💡 Review Order Suggestion
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/page-client.tsxImportant
Enhances team member invitation UI and refactors data fetching in
page-client.tsxfor better usability and robustness.page-client.tsx.TeamAddUserDialogto fetch user and admin data asynchronously instead of using hooks.TeamAddUserDialog.TeamAddUserDialog.This description was created by
for 3e16f0c. You can customize this summary. It will automatically update as commits are pushed.
Summary by CodeRabbit
Refactor
Style
Chores