{
  "name": "WorkspaceMembersPage",
  "package": "@magicblocksai/ui",
  "file": "packages/ui/src/components/WorkspaceMembersPage.tsx",
  "chapterTag": "23 Workspace",
  "chapter": "23-workspace.html",
  "sectionId": null,
  "elName": null,
  "demoUrl": null,
  "hasLiveDemo": false,
  "description": "Page-shaped wrapper composing chapter 25's workspace primitives into a\ncomplete team-administration page layout. Sections render in order:\nMembers → Pending invites → Audit log. The `<TeamHeaderBlock>` sits\nabove the member list with the count pill auto-bound to\n`members.length`; each sub-section gets a small uppercase label above\nits content.",
  "useClient": false,
  "interactivity": "display",
  "namedExports": [
    {
      "name": "WorkspaceMembersPage",
      "isPrincipal": true,
      "isType": false
    },
    {
      "name": "WorkspaceMembersPageProps",
      "isPrincipal": false,
      "isType": true
    }
  ],
  "importStatement": "import { WorkspaceMembersPage } from \"@magicblocksai/ui\";",
  "props": [
    {
      "name": "members",
      "optional": false,
      "type": "MemberRowProps[]",
      "doc": "Active team members rendered inside `.member-list`. One `<MemberRow>` per entry, keyed by `email`. The page header's count pill mirrors `members.length` so the surface stays in sync as the list grows."
    },
    {
      "name": "invites",
      "optional": false,
      "type": "InviteRowProps[]",
      "doc": "Pending invites rendered inside `.invite-list`. One `<InviteRow>` per entry, keyed by `email`. Omit the section by passing an empty array; the sub-header always renders so the surface keeps a stable shape."
    },
    {
      "name": "auditLog",
      "optional": false,
      "type": "AuditLogEntryProps[]",
      "doc": "Audit-log entries rendered inside `.audit-log-stack`. One `<AuditLogEntry>` per entry. Each entry can carry an optional `diff` to surface the chevron-toggle Before / After panel."
    },
    {
      "name": "title",
      "optional": true,
      "type": "ReactNode",
      "doc": "Optional override for the page title. Defaults to `\"Members\"`. Passed through to `<TeamHeaderBlock>`."
    },
    {
      "name": "inviteAction",
      "optional": true,
      "type": "ReactNode",
      "doc": "Optional invite CTA slot — typically a `<button className=\"btn\">`. Passed through to `<TeamHeaderBlock>` and rendered on the right edge of the head row."
    },
    {
      "name": "className",
      "optional": true,
      "type": "string",
      "doc": ""
    }
  ],
  "classesUsed": [
    "audit-log-stack",
    "btn",
    "invite-list",
    "member-list",
    "title",
    "workspace-members-page",
    "workspace-members-page-section",
    "workspace-members-page-section-label"
  ],
  "examples": {
    "react": "<WorkspaceMembersPage\n  title=\"Members\"\n  inviteAction={<button type=\"button\" className=\"btn\">Invite member</button>}\n  members={[\n    { name: \"Jay Stockwell\", email: \"jay@magicblocks.ai\",\n      role: \"admin\", lastActive: \"Active now\" },\n    { name: \"Alex Kim\", email: \"alex@magicblocks.ai\",\n      role: \"editor\", lastActive: \"2 hours ago\" },\n  ]}\n  invites={[\n    { email: \"newdev@example.com\", role: \"editor\",\n      invitedBy: \"Jay\", sentAt: \"2 days ago\",\n      onResend: () => {}, onRevoke: () => {} },\n  ]}\n  auditLog={[\n    { actor: { name: \"Jay Stockwell\" }, verb: \"invited\",\n      target: <strong>jane@example.com</strong>,\n      timestamp: \"2 hours ago\" },\n  ]}\n/>",
    "html": null,
    "css": ".audit-log-stack {\n  display: flex;\n  flex-direction: column;\n  gap: var(--s-3);\n}\n\n.btn {\n  display: inline-flex; align-items: center; justify-content: center;\n  gap: var(--s-2);\n  font: 600 14.5px/1 var(--f-display);\n  letter-spacing: -0.005em;\n  padding: 11px var(--s-5);\n  border: 1px solid transparent;\n  border-radius: var(--r-md);\n  cursor: pointer;\n  text-decoration: none;\n  transition: background var(--dur-2) var(--ease),\n              border-color var(--dur-2) var(--ease),\n              transform var(--dur-2) var(--ease),\n              box-shadow var(--dur-2) var(--ease),\n              color var(--dur-2) var(--ease);\n  user-select: none;\n  white-space: nowrap;\n  appearance: none; -webkit-appearance: none;\n}\n.btn { padding: 11px var(--s-5); font-size: 14.5px; }\n\n.invite-list {\n  list-style: none;\n  margin: 0;\n  padding: 0;\n  border: 1px solid var(--hair);\n  border-radius: var(--r-md);\n  overflow: hidden;\n}\n\n.member-list {\n  list-style: none;\n  margin: 0;\n  padding: 0;\n  display: flex;\n  flex-direction: column;\n  background: var(--bg-paper);\n  border: 1px solid var(--hair);\n  border-radius: var(--r-md);\n  overflow: hidden;\n}\n\n.title { font: 700 32px/1.15 var(--f-display); letter-spacing: -0.015em; margin: 0; }\n\n.workspace-members-page {\n  display: flex;\n  flex-direction: column;\n  gap: var(--s-8);\n}\n\n.workspace-members-page-section {\n  display: flex;\n  flex-direction: column;\n  gap: var(--s-4);\n}\n\n.workspace-members-page-section-label {\n  margin: 0;\n  font: 600 16px/1.2 var(--f-display);\n  text-transform: uppercase;\n  letter-spacing: 0.04em;\n  color: var(--fg-soft);\n}"
  }
}
