-
Notifications
You must be signed in to change notification settings - Fork 5.9k
feat: add invitation and join team features #3577
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: master
Are you sure you want to change the base?
Conversation
|
@TinsFox is attempting to deploy a commit to the umami-software Team on Vercel. A member of the Team first needs to authorize it. |
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.
Greptile Summary
This PR implements a comprehensive team invitation and joining system for the Umami analytics platform. The feature allows team administrators to generate invitation links containing access codes that can be shared with potential team members, streamlining the team collaboration process.
The implementation includes several key components:
-
Team Invitation Generation: The existing
TeamEditFormcomponent now displays a read-only invitation link field that combines the current hostname with/invite?accessCode=and the team's access code. This gives administrators an easy way to generate and share invitation URLs. -
Dedicated Invitation Page: A new
/inviteroute is created withInvitePageand supporting components that handle the invitation workflow. When users visit an invitation link, they land on a dedicated page with a pre-populated form. -
Pre-filled Join Form: The
InviteFormcomponent extracts the access code from URL search parameters and automatically fills in the join form, reducing friction for new team members. The form uses the same/teams/joinAPI endpoint as the existingTeamJoinForm. -
Internationalization Support: New localization keys are added to support the invitation link label across different languages, maintaining the platform's multilingual capabilities.
The feature integrates well with the existing team management infrastructure, reusing established API endpoints and following similar patterns to the existing TeamJoinForm component. The invitation workflow creates a more user-friendly alternative to manually sharing access codes, as users can simply click a link to join a team rather than copying and pasting access codes.
Confidence score: 1/5
- This PR has critical localization and implementation issues that will cause immediate problems in production
- Score reflects a critical localization bug where Chinese text appears in English UI, plus several functional issues in the invitation form
- Pay close attention to
src/lang/en-US.jsonfor the localization error andsrc/app/(main)/invite/InviteForm.tsxfor the non-functional cancel button and missing navigation logic
8 files reviewed, 5 comments
src/app/(main)/invite/InviteForm.tsx
Outdated
| <Button type="submit" variant="primary"> | ||
| {formatMessage(labels.join)} | ||
| </Button> | ||
| <Button onClick={() => {}}>{formatMessage(labels.cancel)}</Button> |
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.
logic: Cancel button has empty onClick handler - users cannot actually cancel or navigate away
| const handleSubmit = async (data: any) => { | ||
| mutate(data, { | ||
| onSuccess: async () => { | ||
| touch('teams:members'); | ||
| }, | ||
| }); |
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.
logic: No navigation or user feedback after successful team join - users may not know the operation completed
| <FormRow label={formatMessage(labels.invitationLink)}> | ||
| <Flexbox gap={10}> | ||
| <TextField | ||
| value={`${window.location.host}/invite?accessCode=${accessCode}`} |
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.
logic: Using window.location.host in a Next.js component can cause hydration errors since window is undefined during server-side rendering. Consider using useEffect to set this value client-side only.
| <FormRow label={formatMessage(labels.invitationLink)}> | ||
| <Flexbox gap={10}> | ||
| <TextField | ||
| value={`${window.location.host}/invite?accessCode=${accessCode}`} | ||
| readOnly | ||
| allowCopy | ||
| /> | ||
| </Flexbox> | ||
| </FormRow> |
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.
logic: The invitation link is shown regardless of cloudMode or allowEdit permissions, while the access code field above is conditionally rendered. Consider if this should have similar conditional logic.
Added a function for generating an invitation link and joining the team through the link, making collaboration more convenient.