Team Collaboration

Manage team members, roles, and permissions in your application.

Note: This is mock/placeholder content for demonstration purposes.

Enable teams to collaborate effectively with built-in team management features.

Team Accounts

The application supports multi-tenant team accounts where multiple users can collaborate.

Creating a Team

Users can create new team accounts:

import { createTeamAccount } from '~/lib/teams/create-team';

const team = await createTeamAccount({
  name: 'Acme Corp',
  slug: 'acme-corp',
  ownerId: currentUser.id,
});

Team Workspace

Each team has its own workspace with isolated data:

  • Projects and resources
  • Team-specific settings
  • Billing and subscription
  • Activity logs

Inviting Members

Send Invitations

Invite new members to your team:

import { inviteTeamMember } from '~/lib/teams/invitations';

await inviteTeamMember({
  teamId: team.id,
  email: 'member@example.com',
  role: 'member',
});

Invitation Flow

  1. Owner sends invitation via email
  2. Recipient receives email with invitation link
  3. Recipient accepts invitation
  4. Member gains access to team workspace

Managing Invitations

import { PendingInvitations } from '~/components/teams/pending-invitations';

<PendingInvitations teamId={team.id} />

Roles and Permissions

Default Roles

Owner

  • Full access to team and settings
  • Manage billing and subscriptions
  • Invite and remove members
  • Delete team

Admin

  • Manage team members
  • Manage team resources
  • Cannot access billing
  • Cannot delete team

Member

  • View team resources
  • Create and edit own content
  • Limited team settings access

Custom Roles

Define custom roles with specific permissions:

const customRole = {
  name: 'Editor',
  permissions: [
    'read:projects',
    'write:projects',
    'read:members',
  ],
};

Checking Permissions

import { checkPermission } from '~/lib/teams/permissions';

const canEdit = await checkPermission(userId, teamId, 'write:projects');

if (!canEdit) {
  throw new Error('Insufficient permissions');
}

Member Management

Listing Members

import { getTeamMembers } from '~/lib/teams/members';

const members = await getTeamMembers(teamId);

Updating Member Role

import { updateMemberRole } from '~/lib/teams/members';

await updateMemberRole({
  memberId: member.id,
  role: 'admin',
});

Removing Members

import { removeMember } from '~/lib/teams/members';

await removeMember(memberId);

Team Settings

Updating Team Info

'use client';

import { useForm } from 'react-hook-form';
import { updateTeamAction } from '../_lib/server/actions';

export function TeamSettingsForm({ team }) {
  const { register, handleSubmit } = useForm({
    defaultValues: {
      name: team.name,
      description: team.description,
    },
  });

  const onSubmit = async (data) => {
    await updateTeamAction({ teamId: team.id, ...data });
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register('name')} placeholder="Team name" />
      <textarea {...register('description')} placeholder="Description" />
      <button type="submit">Save Changes</button>
    </form>
  );
}

Team Avatar

import { uploadTeamAvatar } from '~/lib/teams/avatar';

const avatarUrl = await uploadTeamAvatar({
  teamId: team.id,
  file: avatarFile,
});

Activity Log

Track team activity for transparency:

import { logActivity } from '~/lib/teams/activity';

await logActivity({
  teamId: team.id,
  userId: user.id,
  action: 'member_invited',
  metadata: {
    invitedEmail: 'new@example.com',
  },
});

Viewing Activity

import { getTeamActivity } from '~/lib/teams/activity';

const activities = await getTeamActivity(teamId, {
  limit: 50,
  offset: 0,
});

Team Switching

Allow users to switch between their teams:

'use client';

import { useTeamAccountWorkspace } from '@kit/team-accounts/hooks/use-team-account-workspace';

export function TeamSwitcher() {
  const { accounts, account } = useTeamAccountWorkspace();

  return (
    <select
      value={account.id}
      onChange={(e) => switchTeam(e.target.value)}
    >
      {accounts.map((team) => (
        <option key={team.id} value={team.id}>
          {team.name}
        </option>
      ))}
    </select>
  );
}

Notifications

Member Joined

await createNotification({
  teamId: team.id,
  title: 'New Member',
  message: `${user.name} joined the team`,
  type: 'info',
});

Role Changed

await createNotification({
  userId: member.userId,
  title: 'Role Updated',
  message: `Your role was changed to ${newRole}`,
  type: 'info',
});

Best Practices

  1. Clear role hierarchy - Define roles that make sense for your use case
  2. Principle of least privilege - Give minimum required permissions
  3. Audit trail - Log important team actions
  4. Easy onboarding - Simple invitation process
  5. Self-service - Let members manage their own settings
  6. Transparent billing - Show usage and costs clearly