LogoShip Superfast

Team

Team management — members, invites, roles, and the team switcher.

Overview

The team page lives at /dashboard/team (app/dashboard/team/page.tsx). It lets users manage their team's members and invitations. What you can do depends on your role.

Roles

RoleCan inviteCan remove membersCan change rolesCan rename team
OwnerYesYes (except self)YesYes
AdminYesYes (members only)NoYes
MemberNoNoNoNo

Page sections

Incoming invites

If the current user has pending invitations to other teams, they appear at the top with Accept/Decline buttons. This uses the IncomingInvites component shared with the dashboard overview page.

Team header

Shows the team name, your role, and an edit button (owners and admins only). Clicking edit opens a dialog to rename the team:

const updateName = useMutation(api.teams.updateTeamName);
await updateName({ teamId: team._id, name: newName });

Members table

A table listing all team members with:

  • Avatar, name, and email
  • Role badge (Owner / Admin / Member)
  • Join date
  • Actions dropdown (for users you can manage)

Actions available in the dropdown:

  • Promote to Admin — owner only, for members
  • Demote to Member — owner only, for admins
  • Remove from team — owners can remove anyone, admins can remove members

Invite dialog

Owners and admins see an "Invite" button that opens a dialog:

const inviteMember = useAction(api.teams.inviteMember);

const result = await inviteMember({
  teamId,
  email: "user@example.com",
  role: "member", // or "admin"
});

The invite is sent as an email via Resend. The invitee can accept or decline from their dashboard.

Pending invites table

Shows all outstanding invitations with email, role, date sent, and a cancel button. Only visible to owners and admins.

Danger zone

Non-owners see a "Leave Team" button with a confirmation dialog. Leaving is permanent — you can only rejoin if invited again.

const removeMember = useMutation(api.teams.removeMember);
await removeMember({ teamId, userId: currentUserId });

Team switcher

The team switcher lives in the sidebar header (components/navigation/team-switcher.tsx). It's a dropdown showing all teams the user belongs to, with:

  • Team name and first letter avatar
  • Plan badge (Free / Pro / Max)
  • Checkmark on the active team

Switching teams updates the TeamProvider context, which causes all team-aware components (billing, members, etc.) to re-render with the new team's data. The selection is saved to localStorage.

Key files

FilePurpose
app/dashboard/team/page.tsxTeam page (members, invites, danger zone)
components/navigation/team-switcher.tsxSidebar team dropdown
components/team/incoming-invites.tsxPending invite cards
components/providers/team-provider.tsxuseTeam() context

On this page