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

Event Hire Across Melbourne

One Click Events provides professional event hire services across all Melbourne suburbs including photo booths, DJ services, LED dance floors, games, and decorations. Free delivery within 50km of Melbourne CBD. Serving Inner City, Eastern, South Eastern, Northern, and Western suburbs.