@bettercone/ui
ComponentsTeam

SeatAllocationCard

Display team seat usage with member list

SeatAllocationCard

The SeatAllocationCard component displays organization seat allocation with optional member list.

v0.3.0 Update: Component now auto-fetches seat limits from organization subscription.

Installation

npm install @bettercone/ui

Features

  • Auto-Fetch Mode - Automatically fetches seat data from subscription
  • Presentational Mode - Pass seat data manually via data prop
  • Progress Bar - Visual seat usage indicator
  • Member List - Optional member avatars and names
  • Warning States - Highlights when approaching limit
  • Localization - Full i18n support

Usage

import { AuthUIProvider, SeatAllocationCard } from '@bettercone/ui';
import { authClient } from '@/lib/auth-client';

export default function TeamPage() {
  return (
    <AuthUIProvider authClient={authClient}>
      {/* Auto-fetches seat limit from subscription */}
      <SeatAllocationCard />
    </AuthUIProvider>
  );
}
import { SeatAllocationCard } from '@bettercone/ui';

export default function TeamPage() {
  return (
    <SeatAllocationCard
      data={{
        used: 8,
        limit: 20,
      }}
    />
  );
}
import { AuthUIProvider, SeatAllocationCard } from '@bettercone/ui';
import { authClient } from '@/lib/auth-client';

export default function TeamPage() {
  return (
    <AuthUIProvider authClient={authClient}>
      <SeatAllocationCard 
        showMemberList={true}
        maxMembersShown={5}
      />
    </AuthUIProvider>
  );
}

Props

Prop

Type

Seat Detection

In auto-fetch mode, the component:

  1. Gets active organization from Better Auth session
  2. Fetches organization subscription
  3. Extracts subscription.seats as the limit
  4. Counts organization.members.length as used seats
  5. Calculates usage percentage and warnings
// Internal auto-detection
const { data: activeOrg } = useActiveOrganization();
const { data: subscriptions } = useQuery({
  queryKey: ["subscriptions"],
  queryFn: () => authClient.subscription.list(),
});

const orgSubscription = subscriptions?.find(
  sub => sub.referenceId === activeOrg.id
);

const seatData = {
  used: activeOrg.members.length,
  limit: orgSubscription?.seats || 5, // Default to 5
};

Warning States

The component displays different states based on usage:

UsageStateDescription
< 80%NormalGreen progress bar
80-99%WarningYellow progress bar, warning message
100%At LimitRed progress bar, "Upgrade" button shown

Examples

Example 1: Team Dashboard

import { AuthUIProvider } from '@bettercone/ui';
import { SeatAllocationCard, TeamBillingCard } from '@bettercone/ui';
import { authClient } from '@/lib/auth-client';

export default function TeamDashboard() {
  return (
    <AuthUIProvider authClient={authClient}>
      <div className="grid gap-6 lg:grid-cols-2">
        <SeatAllocationCard showMemberList={true} />
        <TeamBillingCard />
      </div>
    </AuthUIProvider>
  );
}

Example 2: With Upgrade Flow

import { SeatAllocationCard } from '@bettercone/ui';
import { useRouter } from 'next/navigation';

export default function TeamPage() {
  const router = useRouter();

  return (
    <SeatAllocationCard
      data={{ used: 20, limit: 20 }}
      onUpgrade={() => router.push('/org/pricing')}
    />
  );
}

Example 3: Custom Styling

<SeatAllocationCard
  data={{ used: 8, limit: 20 }}
  showMemberList={true}
  classNames={{
    base: "border-2",
    header: "bg-gradient-to-r from-green-500 to-blue-500 text-white",
    progress: "h-3 rounded-full",
    memberList: "gap-2",
  }}
/>

Customization

Custom Localization

const portugueseLocalization = {
  seatAllocation: "Alocação de Assentos",
  seatsUsed: "Assentos Usados",
  of: "de",
  members: "Membros",
  upgradePlan: "Aumentar Plano",
  nearLimit: "Próximo do limite",
  atLimit: "No limite de assentos",
};

<SeatAllocationCard localization={portugueseLocalization} />

Migration from v0.2.x

// Before (v0.2.x)
<SeatAllocationCard 
  used={8}
  limit={20}
  showMemberList={true}
/>

// After (v0.3.0) - Auto-fetch
<AuthUIProvider authClient={authClient}>
  <SeatAllocationCard showMemberList={true} />
</AuthUIProvider>

// After (v0.3.0) - Presentational
<SeatAllocationCard 
  data={{ used: 8, limit: 20 }}
  showMemberList={true}
/>

See Also