@burdenoff/microfe-organization 2026.1026.1 → 2026.1101.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/dist/generated/global-operations.js +57 -58
  2. package/dist/generated/global-operations.js.map +1 -1
  3. package/dist/generated/global-types.js +1 -2
  4. package/dist/generated/global-types.js.map +1 -1
  5. package/dist/node_modules/sonner/dist/index.js +2 -3
  6. package/dist/node_modules/sonner/dist/index.js.map +1 -1
  7. package/dist/node_modules/zod/v4/classic/errors.js +44 -0
  8. package/dist/node_modules/zod/v4/classic/errors.js.map +1 -0
  9. package/dist/node_modules/zod/v4/classic/parse.js +7 -0
  10. package/dist/node_modules/zod/v4/classic/parse.js.map +1 -0
  11. package/dist/node_modules/zod/v4/classic/schemas.js +652 -0
  12. package/dist/node_modules/zod/v4/classic/schemas.js.map +1 -0
  13. package/dist/node_modules/zod/v4/core/api.js +429 -0
  14. package/dist/node_modules/zod/v4/core/api.js.map +1 -0
  15. package/dist/node_modules/zod/v4/core/checks.js +143 -0
  16. package/dist/node_modules/zod/v4/core/checks.js.map +1 -0
  17. package/dist/node_modules/zod/v4/core/core.js +84 -0
  18. package/dist/node_modules/zod/v4/core/core.js.map +1 -0
  19. package/dist/node_modules/zod/v4/core/doc.js +29 -0
  20. package/dist/node_modules/zod/v4/core/doc.js.map +1 -0
  21. package/dist/node_modules/zod/v4/core/errors.js +90 -0
  22. package/dist/node_modules/zod/v4/core/errors.js.map +1 -0
  23. package/dist/node_modules/zod/v4/core/json-schema-processors.js +285 -0
  24. package/dist/node_modules/zod/v4/core/json-schema-processors.js.map +1 -0
  25. package/dist/node_modules/zod/v4/core/memoizer.js +188 -0
  26. package/dist/node_modules/zod/v4/core/memoizer.js.map +1 -0
  27. package/dist/node_modules/zod/v4/core/parse.js +159 -0
  28. package/dist/node_modules/zod/v4/core/parse.js.map +1 -0
  29. package/dist/node_modules/zod/v4/core/regexes.js +34 -0
  30. package/dist/node_modules/zod/v4/core/regexes.js.map +1 -0
  31. package/dist/node_modules/zod/v4/core/registries.js +41 -0
  32. package/dist/node_modules/zod/v4/core/registries.js.map +1 -0
  33. package/dist/node_modules/zod/v4/core/schemas.js +979 -0
  34. package/dist/node_modules/zod/v4/core/schemas.js.map +1 -0
  35. package/dist/node_modules/zod/v4/core/to-json-schema.js +330 -0
  36. package/dist/node_modules/zod/v4/core/to-json-schema.js.map +1 -0
  37. package/dist/node_modules/zod/v4/core/util.js +417 -0
  38. package/dist/node_modules/zod/v4/core/util.js.map +1 -0
  39. package/dist/node_modules/zod/v4/core/versions.js +9 -0
  40. package/dist/node_modules/zod/v4/core/versions.js.map +1 -0
  41. package/dist/node_modules/zod/v4/locales/en.js +96 -0
  42. package/dist/node_modules/zod/v4/locales/en.js.map +1 -0
  43. package/dist/organization-management/AdminOrganizationRoot.js +13 -10
  44. package/dist/organization-management/AdminOrganizationRoot.js.map +1 -1
  45. package/dist/organization-management/AdminOrganizationRoutes.js +8 -9
  46. package/dist/organization-management/AdminOrganizationRoutes.js.map +1 -1
  47. package/dist/organization-management/UserOrganizationRoot.js +13 -10
  48. package/dist/organization-management/UserOrganizationRoot.js.map +1 -1
  49. package/dist/organization-management/UserOrganizationRoutes.js +1 -2
  50. package/dist/organization-management/UserOrganizationRoutes.js.map +1 -1
  51. package/dist/organization-management/constants/permissions.js +1 -2
  52. package/dist/organization-management/constants/permissions.js.map +1 -1
  53. package/dist/organization-management/hooks/useOrganizationEventEmitter.js +1 -2
  54. package/dist/organization-management/hooks/useOrganizationEventEmitter.js.map +1 -1
  55. package/dist/organization-management/hooks/useOrganizationPageView.js +1 -2
  56. package/dist/organization-management/hooks/useOrganizationPageView.js.map +1 -1
  57. package/dist/organization-management/modules/members/components/BulkInviteForm.js +3 -3
  58. package/dist/organization-management/modules/members/components/BulkInviteForm.js.map +1 -1
  59. package/dist/organization-management/modules/members/components/InviteMemberForm.js +1 -2
  60. package/dist/organization-management/modules/members/components/InviteMemberForm.js.map +1 -1
  61. package/dist/organization-management/modules/members/components/InviteStatusBadge.js +1 -2
  62. package/dist/organization-management/modules/members/components/InviteStatusBadge.js.map +1 -1
  63. package/dist/organization-management/modules/members/components/MemberRoleBadge.js +1 -2
  64. package/dist/organization-management/modules/members/components/MemberRoleBadge.js.map +1 -1
  65. package/dist/organization-management/modules/members/components/MyInviteCard.js +5 -6
  66. package/dist/organization-management/modules/members/components/MyInviteCard.js.map +1 -1
  67. package/dist/organization-management/modules/members/components/PendingInvitesList.js +8 -9
  68. package/dist/organization-management/modules/members/components/PendingInvitesList.js.map +1 -1
  69. package/dist/organization-management/modules/members/hooks/useInvites.js +2 -3
  70. package/dist/organization-management/modules/members/hooks/useInvites.js.map +1 -1
  71. package/dist/organization-management/modules/members/hooks/useMembers.js +1 -2
  72. package/dist/organization-management/modules/members/hooks/useMembers.js.map +1 -1
  73. package/dist/organization-management/modules/members/hooks/useWorkspaceInvites.js +1 -2
  74. package/dist/organization-management/modules/members/hooks/useWorkspaceInvites.js.map +1 -1
  75. package/dist/organization-management/modules/members/pages/InviteMemberPage.js +16 -17
  76. package/dist/organization-management/modules/members/pages/InviteMemberPage.js.map +1 -1
  77. package/dist/organization-management/modules/members/pages/InvitePeoplePage.js +14 -15
  78. package/dist/organization-management/modules/members/pages/InvitePeoplePage.js.map +1 -1
  79. package/dist/organization-management/modules/members/pages/MemberDetailPage.js +18 -19
  80. package/dist/organization-management/modules/members/pages/MemberDetailPage.js.map +1 -1
  81. package/dist/organization-management/modules/members/pages/MembersListPage.js +142 -143
  82. package/dist/organization-management/modules/members/pages/MembersListPage.js.map +1 -1
  83. package/dist/organization-management/modules/members/pages/MyInvitesPage.js +168 -169
  84. package/dist/organization-management/modules/members/pages/MyInvitesPage.js.map +1 -1
  85. package/dist/organization-management/modules/members/pages/OrganizationInviteAcceptancePage.js +13 -14
  86. package/dist/organization-management/modules/members/pages/OrganizationInviteAcceptancePage.js.map +1 -1
  87. package/dist/organization-management/modules/members/utils/bulkInviteCsv.js +4 -10
  88. package/dist/organization-management/modules/members/utils/bulkInviteCsv.js.map +1 -1
  89. package/dist/organization-management/modules/members/utils/workspaceInvitationDisplay.js +1 -2
  90. package/dist/organization-management/modules/members/utils/workspaceInvitationDisplay.js.map +1 -1
  91. package/dist/organization-management/modules/organizations/components/OrganizationForm.js +14 -15
  92. package/dist/organization-management/modules/organizations/components/OrganizationForm.js.map +1 -1
  93. package/dist/organization-management/modules/organizations/components/OrganizationStatusBadge.js +1 -2
  94. package/dist/organization-management/modules/organizations/components/OrganizationStatusBadge.js.map +1 -1
  95. package/dist/organization-management/modules/organizations/hooks/useOrganizations.js +2 -3
  96. package/dist/organization-management/modules/organizations/hooks/useOrganizations.js.map +1 -1
  97. package/dist/organization-management/modules/organizations/hooks/useOrgsWithPermission.js +22 -21
  98. package/dist/organization-management/modules/organizations/hooks/useOrgsWithPermission.js.map +1 -1
  99. package/dist/organization-management/modules/organizations/pages/OrganizationCreatePage.js +18 -19
  100. package/dist/organization-management/modules/organizations/pages/OrganizationCreatePage.js.map +1 -1
  101. package/dist/organization-management/modules/organizations/pages/OrganizationDetailPage.js +29 -30
  102. package/dist/organization-management/modules/organizations/pages/OrganizationDetailPage.js.map +1 -1
  103. package/dist/organization-management/modules/organizations/pages/OrganizationEditPage.js +14 -15
  104. package/dist/organization-management/modules/organizations/pages/OrganizationEditPage.js.map +1 -1
  105. package/dist/organization-management/modules/organizations/pages/OrganizationsListPage.js +33 -34
  106. package/dist/organization-management/modules/organizations/pages/OrganizationsListPage.js.map +1 -1
  107. package/dist/organization-management/modules/organizations/schemas/index.js +11 -12
  108. package/dist/organization-management/modules/organizations/schemas/index.js.map +1 -1
  109. package/dist/organization-management/modules/workspaces/components/AddWorkspaceMemberDialog.js +16 -24
  110. package/dist/organization-management/modules/workspaces/components/AddWorkspaceMemberDialog.js.map +1 -1
  111. package/dist/organization-management/modules/workspaces/components/WorkspaceCard.js +5 -6
  112. package/dist/organization-management/modules/workspaces/components/WorkspaceCard.js.map +1 -1
  113. package/dist/organization-management/modules/workspaces/components/WorkspaceForm.js +31 -32
  114. package/dist/organization-management/modules/workspaces/components/WorkspaceForm.js.map +1 -1
  115. package/dist/organization-management/modules/workspaces/components/WorkspaceStatusBadge.js +1 -2
  116. package/dist/organization-management/modules/workspaces/components/WorkspaceStatusBadge.js.map +1 -1
  117. package/dist/organization-management/modules/workspaces/hooks/useWorkspaceMembers.js +1 -2
  118. package/dist/organization-management/modules/workspaces/hooks/useWorkspaceMembers.js.map +1 -1
  119. package/dist/organization-management/modules/workspaces/hooks/useWorkspaces.js +11 -12
  120. package/dist/organization-management/modules/workspaces/hooks/useWorkspaces.js.map +1 -1
  121. package/dist/organization-management/modules/workspaces/pages/WorkspaceCreatePage.js +18 -19
  122. package/dist/organization-management/modules/workspaces/pages/WorkspaceCreatePage.js.map +1 -1
  123. package/dist/organization-management/modules/workspaces/pages/WorkspaceDetailPage.js +43 -44
  124. package/dist/organization-management/modules/workspaces/pages/WorkspaceDetailPage.js.map +1 -1
  125. package/dist/organization-management/modules/workspaces/pages/WorkspaceEditPage.js +19 -20
  126. package/dist/organization-management/modules/workspaces/pages/WorkspaceEditPage.js.map +1 -1
  127. package/dist/organization-management/modules/workspaces/pages/WorkspacesListPage.js +240 -241
  128. package/dist/organization-management/modules/workspaces/pages/WorkspacesListPage.js.map +1 -1
  129. package/dist/organization-management/modules/workspaces/schemas/index.js +6 -7
  130. package/dist/organization-management/modules/workspaces/schemas/index.js.map +1 -1
  131. package/dist/organization-management/providers/OrgConsoleProvider.js +1 -2
  132. package/dist/organization-management/providers/OrgConsoleProvider.js.map +1 -1
  133. package/dist/organization-management/providers/OrgScopedPermissions.js +1 -2
  134. package/dist/organization-management/providers/OrgScopedPermissions.js.map +1 -1
  135. package/dist/organization-management/shared/components/dialog/ConfirmDialog.js +1 -2
  136. package/dist/organization-management/shared/components/dialog/ConfirmDialog.js.map +1 -1
  137. package/dist/organization-management/shared/components/dialog/ConfirmDialogView.js +1 -2
  138. package/dist/organization-management/shared/components/dialog/ConfirmDialogView.js.map +1 -1
  139. package/dist/organization-management/shared/components/feedback/ErrorState.js +1 -2
  140. package/dist/organization-management/shared/components/feedback/ErrorState.js.map +1 -1
  141. package/dist/organization-management/shared/components/feedback/LoadingState.js +1 -2
  142. package/dist/organization-management/shared/components/feedback/LoadingState.js.map +1 -1
  143. package/dist/organization-management/shared/components/input/SearchInput.js +1 -2
  144. package/dist/organization-management/shared/components/input/SearchInput.js.map +1 -1
  145. package/dist/organization-management/shared/components/input/SelectionCheckbox.js +1 -2
  146. package/dist/organization-management/shared/components/input/SelectionCheckbox.js.map +1 -1
  147. package/dist/organization-management/shared/hooks/useDebouncedValue.js +1 -2
  148. package/dist/organization-management/shared/hooks/useDebouncedValue.js.map +1 -1
  149. package/dist/organization-management/shared/hooks/useTr.js +1 -2
  150. package/dist/organization-management/shared/hooks/useTr.js.map +1 -1
  151. package/dist/organization-management/shared/logger.js +1 -2
  152. package/dist/organization-management/shared/logger.js.map +1 -1
  153. package/dist/organization-management/shared/recaptcha.js +1 -2
  154. package/dist/organization-management/shared/recaptcha.js.map +1 -1
  155. package/dist/organization-management/shared/types/graphql.js +1 -2
  156. package/dist/organization-management/shared/types/graphql.js.map +1 -1
  157. package/dist/utils/nativeBridge.js +1 -2
  158. package/package.json +7 -6
  159. package/dist/node_modules/zod/v3/ZodError.js +0 -82
  160. package/dist/node_modules/zod/v3/ZodError.js.map +0 -1
  161. package/dist/node_modules/zod/v3/errors.js +0 -10
  162. package/dist/node_modules/zod/v3/errors.js.map +0 -1
  163. package/dist/node_modules/zod/v3/helpers/errorUtil.js +0 -9
  164. package/dist/node_modules/zod/v3/helpers/errorUtil.js.map +0 -1
  165. package/dist/node_modules/zod/v3/helpers/parseUtil.js +0 -93
  166. package/dist/node_modules/zod/v3/helpers/parseUtil.js.map +0 -1
  167. package/dist/node_modules/zod/v3/helpers/util.js +0 -76
  168. package/dist/node_modules/zod/v3/helpers/util.js.map +0 -1
  169. package/dist/node_modules/zod/v3/locales/en.js +0 -62
  170. package/dist/node_modules/zod/v3/locales/en.js.map +0 -1
  171. package/dist/node_modules/zod/v3/types.js +0 -2441
  172. package/dist/node_modules/zod/v3/types.js.map +0 -1
@@ -2,7 +2,7 @@ import { useTr as e } from "../../../shared/hooks/useTr.js";
2
2
  import { useState as t } from "react";
3
3
  import { Loader2 as n, Mail as r, Send as i } from "lucide-react";
4
4
  import { jsx as a, jsxs as o } from "react/jsx-runtime";
5
- //#region src/organization-management/modules/members/components/InviteMemberForm.tsx
5
+ // src/organization-management/modules/members/components/InviteMemberForm.tsx
6
6
  function s({ organizationId: s, onSubmit: c, onCancel: l, loading: u }) {
7
7
  let d = e(), [f, p] = t({
8
8
  email: "",
@@ -115,7 +115,6 @@ function s({ organizationId: s, onSubmit: c, onCancel: l, loading: u }) {
115
115
  ]
116
116
  });
117
117
  }
118
- //#endregion
119
118
  export { s as InviteMemberForm };
120
119
 
121
120
  //# sourceMappingURL=InviteMemberForm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"InviteMemberForm.js","names":[],"sources":["../../../../../src/organization-management/modules/members/components/InviteMemberForm.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { Loader2, Mail, Send } from 'lucide-react';\nimport { useTr } from '../../../shared/hooks/useTr';\n\ninterface InviteMemberFormProps {\n organizationId: string;\n onSubmit: (data: { organizationId: string; email: string; message?: string }) => Promise<void>;\n onCancel: () => void;\n loading?: boolean;\n}\n\n/**\n * Invite Member Form\n * Email-based form for inviting users to an organization.\n * Role defaults to MEMBER on the backend — admin can change it after the user joins.\n */\nexport function InviteMemberForm({\n organizationId,\n onSubmit,\n onCancel,\n loading,\n}: InviteMemberFormProps) {\n const tr = useTr();\n const [formData, setFormData] = useState({\n email: '',\n message: '',\n });\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n try {\n await onSubmit({\n organizationId,\n email: formData.email,\n message: formData.message || undefined,\n });\n setFormData({ email: '', message: '' });\n } catch {\n // Error is surfaced by the parent page via the mutation hook's error state\n }\n };\n\n return (\n <form onSubmit={handleSubmit} className=\"space-y-5\">\n {/* Email */}\n <div>\n <label\n htmlFor=\"email\"\n className=\"block text-sm font-medium text-[var(--color-text-primary)] mb-1\"\n >\n {tr('members.invite.emailLabel', 'Email Address')}{' '}\n <span className=\"text-[var(--color-status-error-text)]\">*</span>\n </label>\n <div className=\"relative\">\n <div className=\"absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none\">\n <Mail size={16} className=\"text-[var(--color-text-muted)]\" />\n </div>\n <input\n id=\"email\"\n type=\"email\"\n value={formData.email}\n onChange={(e) => setFormData({ ...formData, email: e.target.value })}\n aria-label={tr('members.invite.emailLabel', 'Email Address')}\n className=\"\n w-full pl-10 pr-4 py-2\n bg-[var(--color-bg-surface)]\n border border-[var(--color-border-default)]\n rounded-lg\n text-[var(--color-text-primary)]\n placeholder:text-[var(--color-text-muted)]\n focus:outline-none focus:ring-2 focus:ring-[var(--color-border-focus)]\n disabled:bg-[var(--color-bg-muted)] disabled:cursor-not-allowed\n \"\n placeholder={tr('members.invite.emailPlaceholder', 'user@example.com')}\n disabled={loading}\n required\n />\n </div>\n <p className=\"text-xs text-[var(--color-text-muted)] mt-1\">\n {tr(\n 'members.invite.emailHelp',\n 'The user will be invited as a Member. You can change their role after they join.'\n )}\n </p>\n </div>\n\n {/* Message (optional) */}\n <div>\n <label\n htmlFor=\"message\"\n className=\"block text-sm font-medium text-[var(--color-text-primary)] mb-1\"\n >\n {tr('members.invite.messageLabel', 'Personal Message')}{' '}\n <span className=\"text-[var(--color-text-muted)]\">\n ({tr('common.optional', 'optional')})\n </span>\n </label>\n <textarea\n id=\"message\"\n value={formData.message}\n onChange={(e) => setFormData({ ...formData, message: e.target.value })}\n aria-label={tr('members.invite.messageLabel', 'Personal Message')}\n className=\"\n w-full px-4 py-2\n bg-[var(--color-bg-surface)]\n border border-[var(--color-border-default)]\n rounded-lg\n text-[var(--color-text-primary)]\n placeholder:text-[var(--color-text-muted)]\n focus:outline-none focus:ring-2 focus:ring-[var(--color-border-focus)]\n disabled:bg-[var(--color-bg-muted)] disabled:cursor-not-allowed\n resize-none\n \"\n placeholder={tr(\n 'members.invite.messagePlaceholder',\n 'Add a personal message to the invite...'\n )}\n rows={3}\n maxLength={500}\n disabled={loading}\n />\n </div>\n\n {/* Actions */}\n <div className=\"flex flex-col gap-3 border-t border-[var(--color-border-default)] pt-4 sm:flex-row\">\n <button\n type=\"submit\"\n disabled={loading}\n className=\"\n inline-flex items-center gap-2 px-6 py-2.5\n bg-[var(--color-action-primary-bg)]\n text-[var(--color-action-primary-text)]\n rounded-lg\n hover:opacity-90\n \n transition-all duration-200\n font-medium\n disabled:opacity-50 disabled:cursor-not-allowed\n sm:min-w-[180px]\n \"\n >\n {loading ? <Loader2 size={16} className=\"animate-spin\" /> : <Send size={16} />}\n {tr('members.invite.send', 'Send Invite')}\n </button>\n\n <button\n type=\"button\"\n onClick={onCancel}\n disabled={loading}\n className=\"\n px-6 py-2.5\n bg-transparent\n text-[var(--color-text-primary)]\n border border-[var(--color-border-default)]\n rounded-lg\n hover:bg-[var(--color-bg-subtle)]\n \n transition-all duration-200\n font-medium\n disabled:opacity-50 disabled:cursor-not-allowed\n sm:min-w-[140px]\n \"\n >\n {tr('common.cancel', 'Cancel')}\n </button>\n </div>\n </form>\n );\n}\n"],"mappings":";;;;;AAgBA,SAAgB,EAAiB,EAC/B,mBACA,aACA,aACA,cACwB;CACxB,IAAM,IAAK,GAAO,EACZ,CAAC,GAAU,KAAe,EAAS;EACvC,OAAO;EACP,SAAS;EACV,CAAC;AAgBF,QACE,kBAAC,QAAD;EAAM,UAfa,OAAO,MAAuB;AACjD,KAAE,gBAAgB;AAClB,OAAI;AAMF,IALA,MAAM,EAAS;KACb;KACA,OAAO,EAAS;KAChB,SAAS,EAAS,WAAW,KAAA;KAC9B,CAAC,EACF,EAAY;KAAE,OAAO;KAAI,SAAS;KAAI,CAAC;WACjC;;EAMsB,WAAU;YAAxC;GAEE,kBAAC,OAAD,EAAA,UAAA;IACE,kBAAC,SAAD;KACE,SAAQ;KACR,WAAU;eAFZ;MAIG,EAAG,6BAA6B,gBAAgB;MAAE;MACnD,kBAAC,QAAD;OAAM,WAAU;iBAAwC;OAAQ,CAAA;MAC1D;;IACR,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,GAAD;OAAM,MAAM;OAAI,WAAU;OAAmC,CAAA;MACzD,CAAA,EACN,kBAAC,SAAD;MACE,IAAG;MACH,MAAK;MACL,OAAO,EAAS;MAChB,WAAW,MAAM,EAAY;OAAE,GAAG;OAAU,OAAO,EAAE,OAAO;OAAO,CAAC;MACpE,cAAY,EAAG,6BAA6B,gBAAgB;MAC5D,WAAU;MAUV,aAAa,EAAG,mCAAmC,mBAAmB;MACtE,UAAU;MACV,UAAA;MACA,CAAA,CACE;;IACN,kBAAC,KAAD;KAAG,WAAU;eACV,EACC,4BACA,mFACD;KACC,CAAA;IACA,EAAA,CAAA;GAGN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;IACE,SAAQ;IACR,WAAU;cAFZ;KAIG,EAAG,+BAA+B,mBAAmB;KAAE;KACxD,kBAAC,QAAD;MAAM,WAAU;gBAAhB;OAAiD;OAC7C,EAAG,mBAAmB,WAAW;OAAC;OAC/B;;KACD;OACR,kBAAC,YAAD;IACE,IAAG;IACH,OAAO,EAAS;IAChB,WAAW,MAAM,EAAY;KAAE,GAAG;KAAU,SAAS,EAAE,OAAO;KAAO,CAAC;IACtE,cAAY,EAAG,+BAA+B,mBAAmB;IACjE,WAAU;IAWV,aAAa,EACX,qCACA,0CACD;IACD,MAAM;IACN,WAAW;IACX,UAAU;IACV,CAAA,CACE,EAAA,CAAA;GAGN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,UAAD;KACE,MAAK;KACL,UAAU;KACV,WAAU;eAHZ,CAgBG,IAAU,kBAAC,GAAD;MAAS,MAAM;MAAI,WAAU;MAAiB,CAAA,GAAG,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA,EAC7E,EAAG,uBAAuB,cAAc,CAClC;QAET,kBAAC,UAAD;KACE,MAAK;KACL,SAAS;KACT,UAAU;KACV,WAAU;eAcT,EAAG,iBAAiB,SAAS;KACvB,CAAA,CACL;;GACD"}
1
+ {"version":3,"file":"InviteMemberForm.js","names":["InviteMemberForm","tr","useTr","formData","setFormData","useState","onSubmit","Mail","loading","Loader2","Send","onCancel"],"sources":["../../../../../src/organization-management/modules/members/components/InviteMemberForm.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { Loader2, Mail, Send } from 'lucide-react';\nimport { useTr } from '../../../shared/hooks/useTr';\n\ninterface InviteMemberFormProps {\n organizationId: string;\n onSubmit: (data: { organizationId: string; email: string; message?: string }) => Promise<void>;\n onCancel: () => void;\n loading?: boolean;\n}\n\n/**\n * Invite Member Form\n * Email-based form for inviting users to an organization.\n * Role defaults to MEMBER on the backend — admin can change it after the user joins.\n */\nexport function InviteMemberForm({\n organizationId,\n onSubmit,\n onCancel,\n loading,\n}: InviteMemberFormProps) {\n const tr = useTr();\n const [formData, setFormData] = useState({\n email: '',\n message: '',\n });\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n try {\n await onSubmit({\n organizationId,\n email: formData.email,\n message: formData.message || undefined,\n });\n setFormData({ email: '', message: '' });\n } catch {\n // Error is surfaced by the parent page via the mutation hook's error state\n }\n };\n\n return (\n <form onSubmit={handleSubmit} className=\"space-y-5\">\n {/* Email */}\n <div>\n <label\n htmlFor=\"email\"\n className=\"block text-sm font-medium text-[var(--color-text-primary)] mb-1\"\n >\n {tr('members.invite.emailLabel', 'Email Address')}{' '}\n <span className=\"text-[var(--color-status-error-text)]\">*</span>\n </label>\n <div className=\"relative\">\n <div className=\"absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none\">\n <Mail size={16} className=\"text-[var(--color-text-muted)]\" />\n </div>\n <input\n id=\"email\"\n type=\"email\"\n value={formData.email}\n onChange={(e) => setFormData({ ...formData, email: e.target.value })}\n aria-label={tr('members.invite.emailLabel', 'Email Address')}\n className=\"\n w-full pl-10 pr-4 py-2\n bg-[var(--color-bg-surface)]\n border border-[var(--color-border-default)]\n rounded-lg\n text-[var(--color-text-primary)]\n placeholder:text-[var(--color-text-muted)]\n focus:outline-none focus:ring-2 focus:ring-[var(--color-border-focus)]\n disabled:bg-[var(--color-bg-muted)] disabled:cursor-not-allowed\n \"\n placeholder={tr('members.invite.emailPlaceholder', 'user@example.com')}\n disabled={loading}\n required\n />\n </div>\n <p className=\"text-xs text-[var(--color-text-muted)] mt-1\">\n {tr(\n 'members.invite.emailHelp',\n 'The user will be invited as a Member. You can change their role after they join.'\n )}\n </p>\n </div>\n\n {/* Message (optional) */}\n <div>\n <label\n htmlFor=\"message\"\n className=\"block text-sm font-medium text-[var(--color-text-primary)] mb-1\"\n >\n {tr('members.invite.messageLabel', 'Personal Message')}{' '}\n <span className=\"text-[var(--color-text-muted)]\">\n ({tr('common.optional', 'optional')})\n </span>\n </label>\n <textarea\n id=\"message\"\n value={formData.message}\n onChange={(e) => setFormData({ ...formData, message: e.target.value })}\n aria-label={tr('members.invite.messageLabel', 'Personal Message')}\n className=\"\n w-full px-4 py-2\n bg-[var(--color-bg-surface)]\n border border-[var(--color-border-default)]\n rounded-lg\n text-[var(--color-text-primary)]\n placeholder:text-[var(--color-text-muted)]\n focus:outline-none focus:ring-2 focus:ring-[var(--color-border-focus)]\n disabled:bg-[var(--color-bg-muted)] disabled:cursor-not-allowed\n resize-none\n \"\n placeholder={tr(\n 'members.invite.messagePlaceholder',\n 'Add a personal message to the invite...'\n )}\n rows={3}\n maxLength={500}\n disabled={loading}\n />\n </div>\n\n {/* Actions */}\n <div className=\"flex flex-col gap-3 border-t border-[var(--color-border-default)] pt-4 sm:flex-row\">\n <button\n type=\"submit\"\n disabled={loading}\n className=\"\n inline-flex items-center gap-2 px-6 py-2.5\n bg-[var(--color-action-primary-bg)]\n text-[var(--color-action-primary-text)]\n rounded-lg\n hover:opacity-90\n \n transition-all duration-200\n font-medium\n disabled:opacity-50 disabled:cursor-not-allowed\n sm:min-w-[180px]\n \"\n >\n {loading ? <Loader2 size={16} className=\"animate-spin\" /> : <Send size={16} />}\n {tr('members.invite.send', 'Send Invite')}\n </button>\n\n <button\n type=\"button\"\n onClick={onCancel}\n disabled={loading}\n className=\"\n px-6 py-2.5\n bg-transparent\n text-[var(--color-text-primary)]\n border border-[var(--color-border-default)]\n rounded-lg\n hover:bg-[var(--color-bg-subtle)]\n \n transition-all duration-200\n font-medium\n disabled:opacity-50 disabled:cursor-not-allowed\n sm:min-w-[140px]\n \"\n >\n {tr('common.cancel', 'Cancel')}\n </button>\n </div>\n </form>\n );\n}\n"],"mappings":";;;;;AAgBA,SAAgBA,EAAiB,EAC/B,mBACA,aACA,aACA,cACwB;CACxB,IAAMC,IAAKC,EAAM,GACX,CAACC,GAAUC,KAAeC,EAAS;EACvC,OAAO;EACP,SAAS;CACX,CAAC;CAgBD,OACE,kBAAC,QAAD;EAAM,UAAU,OAfU,MAAuB;GACjD,EAAE,eAAe;GACjB,IAAI;IAMF,AALA,MAAMC,EAAS;KACb;KACA,OAAOH,EAAS;KAChB,SAASA,EAAS,WAAW,KAAA;IAC/B,CAAC,GACDC,EAAY;KAAE,OAAO;KAAI,SAAS;IAAG,CAAC;GACxC,QAAQ,CAER;EACF;EAGgC,WAAU;EAAxC,UAAA;GAEE,kBAAC,OAAD,EAAA,UAAA;IACE,kBAAC,SAAD;KACE,SAAQ;KACR,WAAU;KAFZ,UAAA;MAIGH,EAAG,6BAA6B,eAAe;MAAG;MACnD,kBAAC,QAAD;OAAM,WAAU;OAAwC,UAAA;MAAO,CAAA;KAC1D;;IACP,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,kBAAC,OAAD;MAAK,WAAU;MACb,UAAA,kBAACM,GAAD;OAAM,MAAM;OAAI,WAAU;MAAkC,CAAA;KACzD,CAAA,GACL,kBAAC,SAAD;MACE,IAAG;MACH,MAAK;MACL,OAAOJ,EAAS;MAChB,WAAW,MAAMC,EAAY;OAAE,GAAGD;OAAU,OAAO,EAAE,OAAO;MAAM,CAAC;MACnE,cAAYF,EAAG,6BAA6B,eAAe;MAC3D,WAAU;MAUV,aAAaA,EAAG,mCAAmC,kBAAkB;MACrE,UAAUO;MACV,UAAA;KACD,CAAA,CACE;;IACL,kBAAC,KAAD;KAAG,WAAU;KACV,UAAAP,EACC,4BACA,kFACF;IACC,CAAA;GACA,EAAA,CAAA;GAGL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;IACE,SAAQ;IACR,WAAU;IAFZ,UAAA;KAIGA,EAAG,+BAA+B,kBAAkB;KAAG;KACxD,kBAAC,QAAD;MAAM,WAAU;MAAhB,UAAA;OAAiD;OAC7CA,EAAG,mBAAmB,UAAU;OAAE;MAChC;;IACD;GACP,CAAA,GAAA,kBAAC,YAAD;IACE,IAAG;IACH,OAAOE,EAAS;IAChB,WAAW,MAAMC,EAAY;KAAE,GAAGD;KAAU,SAAS,EAAE,OAAO;IAAM,CAAC;IACrE,cAAYF,EAAG,+BAA+B,kBAAkB;IAChE,WAAU;IAWV,aAAaA,EACX,qCACA,yCACF;IACA,MAAM;IACN,WAAW;IACX,UAAUO;GACX,CAAA,CACE,EAAA,CAAA;GAGL,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,kBAAC,UAAD;KACE,MAAK;KACL,UAAUA;KACV,WAAU;KAHZ,UAAA,CAgBGA,IAAU,kBAACC,GAAD;MAAS,MAAM;MAAI,WAAU;KAAgB,CAAA,IAAI,kBAACC,GAAD,EAAM,MAAM,GAAK,CAAA,GAC5ET,EAAG,uBAAuB,aAAa,CAClC;IAER,CAAA,GAAA,kBAAC,UAAD;KACE,MAAK;KACL,SAASU;KACT,UAAUH;KACV,WAAU;KAcT,UAAAP,EAAG,iBAAiB,QAAQ;IACvB,CAAA,CACL;;EACD;;AAEV"}
@@ -2,7 +2,7 @@ import { useCallback as e } from "react";
2
2
  import { AlertTriangle as t, Ban as n, Check as r, Clock as i, X as a } from "lucide-react";
3
3
  import { jsx as o, jsxs as s } from "react/jsx-runtime";
4
4
  import { useI18n as c } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
5
- //#region src/organization-management/modules/members/components/InviteStatusBadge.tsx
5
+ // src/organization-management/modules/members/components/InviteStatusBadge.tsx
6
6
  var l = {
7
7
  PENDING: {
8
8
  labelKey: "members.inviteStatus.pending",
@@ -49,7 +49,6 @@ function u({ status: t }) {
49
49
  }), r(i.labelKey, i.defaultLabel)]
50
50
  });
51
51
  }
52
- //#endregion
53
52
  export { u as InviteStatusBadge };
54
53
 
55
54
  //# sourceMappingURL=InviteStatusBadge.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"InviteStatusBadge.js","names":[],"sources":["../../../../../src/organization-management/modules/members/components/InviteStatusBadge.tsx"],"sourcesContent":["import { Clock, Check, X, AlertTriangle, Ban } from 'lucide-react';\nimport { useCallback } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\ninterface InviteStatusBadgeProps {\n status: string;\n}\n\nconst STATUS_CONFIG: Record<\n string,\n { labelKey: string; defaultLabel: string; className: string; icon: typeof Clock; pulse?: boolean }\n> = {\n PENDING: {\n labelKey: 'members.inviteStatus.pending',\n defaultLabel: 'Pending',\n className:\n 'bg-[var(--color-status-warning-bgSubtle)] text-[var(--color-status-warning-text)] border border-[var(--color-status-warning-border)]',\n icon: Clock,\n pulse: true,\n },\n ACCEPTED: {\n labelKey: 'members.inviteStatus.accepted',\n defaultLabel: 'Accepted',\n className:\n 'bg-[var(--color-status-success-bgSubtle)] text-[var(--color-status-success-text)] border border-[var(--color-status-success-border)]',\n icon: Check,\n },\n REJECTED: {\n labelKey: 'members.inviteStatus.rejected',\n defaultLabel: 'Rejected',\n className:\n 'bg-[var(--color-status-error-bgSubtle)] text-[var(--color-status-error-text)] border border-[var(--color-status-error-border)]',\n icon: X,\n },\n EXPIRED: {\n labelKey: 'members.inviteStatus.expired',\n defaultLabel: 'Expired',\n className:\n 'bg-[var(--color-bg-muted)] text-[var(--color-text-secondary)] border border-[var(--color-border-default)]',\n icon: AlertTriangle,\n },\n CANCELLED: {\n labelKey: 'members.inviteStatus.cancelled',\n defaultLabel: 'Cancelled',\n className:\n 'bg-[var(--color-bg-muted)] text-[var(--color-text-secondary)] border border-[var(--color-border-default)]',\n icon: Ban,\n },\n};\n\nexport function InviteStatusBadge({ status }: InviteStatusBadgeProps) {\n const { t } = useI18n();\n const tr = useCallback(\n (key: string, fallback: string) => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n },\n [t]\n );\n const config = STATUS_CONFIG[status] ?? STATUS_CONFIG.PENDING;\n const Icon = config.icon;\n\n return (\n <span\n className={`inline-flex items-center gap-1 px-2.5 py-0.5 rounded-full text-xs font-medium ${config.className}`}\n >\n <Icon size={12} className={config.pulse ? 'motion-safe:animate-vc-glow-pulse' : ''} />\n {tr(config.labelKey, config.defaultLabel)}\n </span>\n );\n}\n"],"mappings":";;;;;AAQA,IAAM,IAGF;CACF,SAAS;EACP,UAAU;EACV,cAAc;EACd,WACE;EACF,MAAM;EACN,OAAO;EACR;CACD,UAAU;EACR,UAAU;EACV,cAAc;EACd,WACE;EACF,MAAM;EACP;CACD,UAAU;EACR,UAAU;EACV,cAAc;EACd,WACE;EACF,MAAM;EACP;CACD,SAAS;EACP,UAAU;EACV,cAAc;EACd,WACE;EACF,MAAM;EACP;CACD,WAAW;EACT,UAAU;EACV,cAAc;EACd,WACE;EACF,MAAM;EACP;CACF;AAED,SAAgB,EAAkB,EAAE,aAAkC;CACpE,IAAM,EAAE,SAAM,GAAS,EACjB,IAAK,GACR,GAAa,MAAqB;EACjC,IAAM,IAAa,EAAE,EAAI;AACzB,SAAO,MAAe,IAAM,IAAW;IAEzC,CAAC,EAAE,CACJ,EACK,IAAS,EAAc,MAAW,EAAc,SAChD,IAAO,EAAO;AAEpB,QACE,kBAAC,QAAD;EACE,WAAW,iFAAiF,EAAO;YADrG,CAGE,kBAAC,GAAD;GAAM,MAAM;GAAI,WAAW,EAAO,QAAQ,sCAAsC;GAAM,CAAA,EACrF,EAAG,EAAO,UAAU,EAAO,aAAa,CACpC"}
1
+ {"version":3,"file":"InviteStatusBadge.js","names":["STATUS_CONFIG","Clock","Check","X","AlertTriangle","Ban","InviteStatusBadge","useI18n","tr","useCallback","translated","t","key","fallback","config","status","Icon"],"sources":["../../../../../src/organization-management/modules/members/components/InviteStatusBadge.tsx"],"sourcesContent":["import { Clock, Check, X, AlertTriangle, Ban } from 'lucide-react';\nimport { useCallback } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\ninterface InviteStatusBadgeProps {\n status: string;\n}\n\nconst STATUS_CONFIG: Record<\n string,\n { labelKey: string; defaultLabel: string; className: string; icon: typeof Clock; pulse?: boolean }\n> = {\n PENDING: {\n labelKey: 'members.inviteStatus.pending',\n defaultLabel: 'Pending',\n className:\n 'bg-[var(--color-status-warning-bgSubtle)] text-[var(--color-status-warning-text)] border border-[var(--color-status-warning-border)]',\n icon: Clock,\n pulse: true,\n },\n ACCEPTED: {\n labelKey: 'members.inviteStatus.accepted',\n defaultLabel: 'Accepted',\n className:\n 'bg-[var(--color-status-success-bgSubtle)] text-[var(--color-status-success-text)] border border-[var(--color-status-success-border)]',\n icon: Check,\n },\n REJECTED: {\n labelKey: 'members.inviteStatus.rejected',\n defaultLabel: 'Rejected',\n className:\n 'bg-[var(--color-status-error-bgSubtle)] text-[var(--color-status-error-text)] border border-[var(--color-status-error-border)]',\n icon: X,\n },\n EXPIRED: {\n labelKey: 'members.inviteStatus.expired',\n defaultLabel: 'Expired',\n className:\n 'bg-[var(--color-bg-muted)] text-[var(--color-text-secondary)] border border-[var(--color-border-default)]',\n icon: AlertTriangle,\n },\n CANCELLED: {\n labelKey: 'members.inviteStatus.cancelled',\n defaultLabel: 'Cancelled',\n className:\n 'bg-[var(--color-bg-muted)] text-[var(--color-text-secondary)] border border-[var(--color-border-default)]',\n icon: Ban,\n },\n};\n\nexport function InviteStatusBadge({ status }: InviteStatusBadgeProps) {\n const { t } = useI18n();\n const tr = useCallback(\n (key: string, fallback: string) => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n },\n [t]\n );\n const config = STATUS_CONFIG[status] ?? STATUS_CONFIG.PENDING;\n const Icon = config.icon;\n\n return (\n <span\n className={`inline-flex items-center gap-1 px-2.5 py-0.5 rounded-full text-xs font-medium ${config.className}`}\n >\n <Icon size={12} className={config.pulse ? 'motion-safe:animate-vc-glow-pulse' : ''} />\n {tr(config.labelKey, config.defaultLabel)}\n </span>\n );\n}\n"],"mappings":";;;;;AAQA,IAAMA,IAGF;CACF,SAAS;EACP,UAAU;EACV,cAAc;EACd,WACE;EACF,MAAMC;EACN,OAAO;CACT;CACA,UAAU;EACR,UAAU;EACV,cAAc;EACd,WACE;EACF,MAAMC;CACR;CACA,UAAU;EACR,UAAU;EACV,cAAc;EACd,WACE;EACF,MAAMC;CACR;CACA,SAAS;EACP,UAAU;EACV,cAAc;EACd,WACE;EACF,MAAMC;CACR;CACA,WAAW;EACT,UAAU;EACV,cAAc;EACd,WACE;EACF,MAAMC;CACR;AACF;AAEA,SAAgBC,EAAkB,EAAE,aAAkC;CACpE,IAAM,EAAE,SAAMC,EAAQ,GAChBC,IAAKC,GACR,GAAa,MAAqB;EACjC,IAAMC,IAAaC,EAAEC,CAAG;EACxB,OAAOF,MAAeE,IAAMC,IAAWH;CACzC,GACA,CAACC,CAAC,CACJ,GACMG,IAASd,EAAce,MAAWf,EAAc,SAChDgB,IAAOF,EAAO;CAEpB,OACE,kBAAC,QAAD;EACE,WAAW,iFAAiFA,EAAO;EADrG,UAAA,CAGE,kBAACE,GAAD;GAAM,MAAM;GAAI,WAAWF,EAAO,QAAQ,sCAAsC;EAAK,CAAA,GACpFN,EAAGM,EAAO,UAAUA,EAAO,YAAY,CACpC;;AAEV"}
@@ -2,7 +2,7 @@ import { useCallback as e } from "react";
2
2
  import { Eye as t, Shield as n, UserCheck as r } from "lucide-react";
3
3
  import { jsx as i, jsxs as a } from "react/jsx-runtime";
4
4
  import { useI18n as o } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
5
- //#region src/organization-management/modules/members/components/MemberRoleBadge.tsx
5
+ // src/organization-management/modules/members/components/MemberRoleBadge.tsx
6
6
  function s({ role: s, showIcon: c = !0 }) {
7
7
  let { t: l } = o(), u = e((e, t) => {
8
8
  let n = l(e);
@@ -50,7 +50,6 @@ function s({ role: s, showIcon: c = !0 }) {
50
50
  children: [c && /* @__PURE__ */ i(f, { size: 14 }), d.label]
51
51
  });
52
52
  }
53
- //#endregion
54
53
  export { s as MemberRoleBadge };
55
54
 
56
55
  //# sourceMappingURL=MemberRoleBadge.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MemberRoleBadge.js","names":[],"sources":["../../../../../src/organization-management/modules/members/components/MemberRoleBadge.tsx"],"sourcesContent":["import { Shield, UserCheck, Eye } from 'lucide-react';\nimport { useCallback } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\ninterface MemberRoleBadgeProps {\n role: string;\n showIcon?: boolean;\n}\n\n/**\n * MemberRoleBadge\n * Displays a role badge for a member with appropriate styling\n */\nexport function MemberRoleBadge({ role, showIcon = true }: MemberRoleBadgeProps) {\n const { t } = useI18n();\n const tr = useCallback(\n (key: string, fallback: string) => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n },\n [t]\n );\n const getRoleConfig = () => {\n const roleUpper = role.toUpperCase();\n\n switch (roleUpper) {\n case 'SUPER_ADMIN':\n return {\n label: tr('members.role.superAdmin', 'Super Admin'),\n icon: Shield,\n className:\n 'bg-[var(--color-status-error-bgSubtle)] text-[var(--color-status-error-text)] border-[var(--color-status-error-border)]',\n };\n case 'TENANT_ADMIN':\n case 'ORG_ADMIN':\n case 'WORKSPACE_ADMIN':\n return {\n label:\n roleUpper === 'TENANT_ADMIN'\n ? tr('members.role.tenantAdmin', 'Tenant Admin')\n : roleUpper === 'ORG_ADMIN'\n ? tr('members.role.orgAdmin', 'Org Admin')\n : tr('members.role.workspaceAdmin', 'Workspace Admin'),\n icon: Shield,\n className:\n 'bg-[var(--color-status-warning-bgSubtle)] text-[var(--color-status-warning-text)] border-[var(--color-status-warning-border)]',\n };\n case 'MEMBER':\n return {\n label: tr('members.role.member', 'Member'),\n icon: UserCheck,\n className:\n 'bg-[var(--color-status-info-bgSubtle)] text-[var(--color-status-info-text)] border-[var(--color-status-info-border)]',\n };\n case 'GUEST':\n return {\n label: tr('members.role.guest', 'Guest'),\n icon: Eye,\n className:\n 'bg-[var(--color-bg-muted)] text-[var(--color-text-secondary)] border-[var(--color-border-default)]',\n };\n default:\n return {\n label: role,\n icon: UserCheck,\n className:\n 'bg-[var(--color-bg-muted)] text-[var(--color-text-secondary)] border-[var(--color-border-default)]',\n };\n }\n };\n\n const config = getRoleConfig();\n const Icon = config.icon;\n\n return (\n <span\n className={`\n inline-flex items-center gap-1.5 px-2.5 py-1\n text-xs font-medium rounded-md\n border\n transition-colors duration-200\n ${config.className}\n `}\n >\n {showIcon && <Icon size={14} />}\n {config.label}\n </span>\n );\n}\n"],"mappings":";;;;;AAaA,SAAgB,EAAgB,EAAE,SAAM,cAAW,MAA8B;CAC/E,IAAM,EAAE,SAAM,GAAS,EACjB,IAAK,GACR,GAAa,MAAqB;EACjC,IAAM,IAAa,EAAE,EAAI;AACzB,SAAO,MAAe,IAAM,IAAW;IAEzC,CAAC,EAAE,CACJ,EAkDK,WAjDsB;EAC1B,IAAM,IAAY,EAAK,aAAa;AAEpC,UAAQ,GAAR;GACE,KAAK,cACH,QAAO;IACL,OAAO,EAAG,2BAA2B,cAAc;IACnD,MAAM;IACN,WACE;IACH;GACH,KAAK;GACL,KAAK;GACL,KAAK,kBACH,QAAO;IACL,OACE,MAAc,iBACV,EAAG,4BAA4B,eAAe,GAC9C,MAAc,cACZ,EAAG,yBAAyB,YAAY,GACxC,EAAG,+BAA+B,kBAAkB;IAC5D,MAAM;IACN,WACE;IACH;GACH,KAAK,SACH,QAAO;IACL,OAAO,EAAG,uBAAuB,SAAS;IAC1C,MAAM;IACN,WACE;IACH;GACH,KAAK,QACH,QAAO;IACL,OAAO,EAAG,sBAAsB,QAAQ;IACxC,MAAM;IACN,WACE;IACH;GACH,QACE,QAAO;IACL,OAAO;IACP,MAAM;IACN,WACE;IACH;;KAIuB,EACxB,IAAO,EAAO;AAEpB,QACE,kBAAC,QAAD;EACE,WAAW;;;;;UAKP,EAAO,UAAU;;YANvB,CASG,KAAY,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA,EAC9B,EAAO,MACH"}
1
+ {"version":3,"file":"MemberRoleBadge.js","names":["MemberRoleBadge","useI18n","tr","useCallback","translated","t","key","fallback","config","roleUpper","role","Shield","UserCheck","Eye","Icon","showIcon"],"sources":["../../../../../src/organization-management/modules/members/components/MemberRoleBadge.tsx"],"sourcesContent":["import { Shield, UserCheck, Eye } from 'lucide-react';\nimport { useCallback } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\ninterface MemberRoleBadgeProps {\n role: string;\n showIcon?: boolean;\n}\n\n/**\n * MemberRoleBadge\n * Displays a role badge for a member with appropriate styling\n */\nexport function MemberRoleBadge({ role, showIcon = true }: MemberRoleBadgeProps) {\n const { t } = useI18n();\n const tr = useCallback(\n (key: string, fallback: string) => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n },\n [t]\n );\n const getRoleConfig = () => {\n const roleUpper = role.toUpperCase();\n\n switch (roleUpper) {\n case 'SUPER_ADMIN':\n return {\n label: tr('members.role.superAdmin', 'Super Admin'),\n icon: Shield,\n className:\n 'bg-[var(--color-status-error-bgSubtle)] text-[var(--color-status-error-text)] border-[var(--color-status-error-border)]',\n };\n case 'TENANT_ADMIN':\n case 'ORG_ADMIN':\n case 'WORKSPACE_ADMIN':\n return {\n label:\n roleUpper === 'TENANT_ADMIN'\n ? tr('members.role.tenantAdmin', 'Tenant Admin')\n : roleUpper === 'ORG_ADMIN'\n ? tr('members.role.orgAdmin', 'Org Admin')\n : tr('members.role.workspaceAdmin', 'Workspace Admin'),\n icon: Shield,\n className:\n 'bg-[var(--color-status-warning-bgSubtle)] text-[var(--color-status-warning-text)] border-[var(--color-status-warning-border)]',\n };\n case 'MEMBER':\n return {\n label: tr('members.role.member', 'Member'),\n icon: UserCheck,\n className:\n 'bg-[var(--color-status-info-bgSubtle)] text-[var(--color-status-info-text)] border-[var(--color-status-info-border)]',\n };\n case 'GUEST':\n return {\n label: tr('members.role.guest', 'Guest'),\n icon: Eye,\n className:\n 'bg-[var(--color-bg-muted)] text-[var(--color-text-secondary)] border-[var(--color-border-default)]',\n };\n default:\n return {\n label: role,\n icon: UserCheck,\n className:\n 'bg-[var(--color-bg-muted)] text-[var(--color-text-secondary)] border-[var(--color-border-default)]',\n };\n }\n };\n\n const config = getRoleConfig();\n const Icon = config.icon;\n\n return (\n <span\n className={`\n inline-flex items-center gap-1.5 px-2.5 py-1\n text-xs font-medium rounded-md\n border\n transition-colors duration-200\n ${config.className}\n `}\n >\n {showIcon && <Icon size={14} />}\n {config.label}\n </span>\n );\n}\n"],"mappings":";;;;;AAaA,SAAgBA,EAAgB,EAAE,SAAM,cAAW,MAA8B;CAC/E,IAAM,EAAE,SAAMC,EAAQ,GAChBC,IAAKC,GACR,GAAa,MAAqB;EACjC,IAAMC,IAAaC,EAAEC,CAAG;EACxB,OAAOF,MAAeE,IAAMC,IAAWH;CACzC,GACA,CAACC,CAAC,CACJ,GAkDMG,WAjDsB;EAC1B,IAAMC,IAAYC,EAAK,YAAY;EAEnC,QAAQD,GAAR;GACE,KAAK,eACH,OAAO;IACL,OAAOP,EAAG,2BAA2B,aAAa;IAClD,MAAMS;IACN,WACE;GACJ;GACF,KAAK;GACL,KAAK;GACL,KAAK,mBACH,OAAO;IACL,OACEF,MAAc,iBACVP,EAAG,4BAA4B,cAAc,IAC7CO,MAAc,cACZP,EAAG,yBAAyB,WAAW,IACvCA,EAAG,+BAA+B,iBAAiB;IAC3D,MAAMS;IACN,WACE;GACJ;GACF,KAAK,UACH,OAAO;IACL,OAAOT,EAAG,uBAAuB,QAAQ;IACzC,MAAMU;IACN,WACE;GACJ;GACF,KAAK,SACH,OAAO;IACL,OAAOV,EAAG,sBAAsB,OAAO;IACvC,MAAMW;IACN,WACE;GACJ;GACF,SACE,OAAO;IACL,OAAOH;IACP,MAAME;IACN,WACE;GACJ;EACJ;CACF,EAEe,CAAc,GACvBE,IAAON,EAAO;CAEpB,OACE,kBAAC,QAAD;EACE,WAAW;;;;;UAKPA,EAAO,UAAU;;EANvB,UAAA,CASGO,KAAY,kBAACD,GAAD,EAAM,MAAM,GAAK,CAAA,GAC7BN,EAAO,KACJ;;AAEV"}
@@ -1,10 +1,10 @@
1
- import { useTr as e } from "../../../shared/hooks/useTr.js";
2
- import { MemberRoleBadge as t } from "./MemberRoleBadge.js";
1
+ import { MemberRoleBadge as e } from "./MemberRoleBadge.js";
2
+ import { useTr as t } from "../../../shared/hooks/useTr.js";
3
3
  import { Building2 as n, Check as r, Clock as i, Loader2 as a, X as o } from "lucide-react";
4
4
  import { jsx as s, jsxs as c } from "react/jsx-runtime";
5
- //#region src/organization-management/modules/members/components/MyInviteCard.tsx
5
+ // src/organization-management/modules/members/components/MyInviteCard.tsx
6
6
  function l({ invite: l, onAccept: u, onReject: d, accepting: f, rejecting: p }) {
7
- let m = e(), h = Math.max(0, Math.ceil((new Date(l.expiresAt).getTime() - Date.now()) / (1e3 * 60 * 60 * 24)));
7
+ let m = t(), h = Math.max(0, Math.ceil((new Date(l.expiresAt).getTime() - Date.now()) / 864e5));
8
8
  return /* @__PURE__ */ s("div", {
9
9
  className: "rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] p-5 transition-colors hover:border-[var(--color-border-focus)]",
10
10
  children: /* @__PURE__ */ c("div", {
@@ -26,7 +26,7 @@ function l({ invite: l, onAccept: u, onReject: d, accepting: f, rejecting: p })
26
26
  }),
27
27
  /* @__PURE__ */ c("div", {
28
28
  className: "flex items-center gap-2 mt-1",
29
- children: [/* @__PURE__ */ s(t, { role: l.role }), /* @__PURE__ */ c("span", {
29
+ children: [/* @__PURE__ */ s(e, { role: l.role }), /* @__PURE__ */ c("span", {
30
30
  className: "text-xs text-[var(--color-text-muted)] flex items-center gap-1",
31
31
  children: [/* @__PURE__ */ s(i, { size: 12 }), h > 0 ? `${m("members.myInvites.expiresIn", "Expires in")} ${h}d` : m("members.myInvites.expiringSoon", "Expiring soon")]
32
32
  })]
@@ -66,7 +66,6 @@ function l({ invite: l, onAccept: u, onReject: d, accepting: f, rejecting: p })
66
66
  })
67
67
  });
68
68
  }
69
- //#endregion
70
69
  export { l as MyInviteCard };
71
70
 
72
71
  //# sourceMappingURL=MyInviteCard.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MyInviteCard.js","names":[],"sources":["../../../../../src/organization-management/modules/members/components/MyInviteCard.tsx"],"sourcesContent":["import { Check, X, Building2, Clock, Loader2 } from 'lucide-react';\nimport { MemberRoleBadge } from './MemberRoleBadge';\nimport { useTr } from '../../../shared/hooks/useTr';\n\ninterface MyInviteCardProps {\n invite: {\n id: string;\n email: string;\n role: string;\n expiresAt: string;\n message?: string | null;\n createdAt: string;\n organization?: {\n id: string;\n name: string;\n slug: string;\n } | null;\n };\n onAccept: (inviteId: string) => Promise<void>;\n onReject: (inviteId: string) => Promise<void>;\n accepting?: boolean;\n rejecting?: boolean;\n}\n\nexport function MyInviteCard({\n invite,\n onAccept,\n onReject,\n accepting,\n rejecting,\n}: MyInviteCardProps) {\n const tr = useTr();\n const daysUntilExpiry = Math.max(\n 0,\n Math.ceil((new Date(invite.expiresAt).getTime() - Date.now()) / (1000 * 60 * 60 * 24))\n );\n\n return (\n <div className=\"rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] p-5 transition-colors hover:border-[var(--color-border-focus)]\">\n <div className=\"flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between\">\n {/* Left: Org info */}\n <div className=\"flex items-start gap-3 min-w-0\">\n <div className=\"p-2 rounded-lg bg-[var(--color-bg-subtle)]\">\n <Building2 size={20} className=\"text-[var(--color-text-secondary)]\" />\n </div>\n <div className=\"min-w-0\">\n <h3 className=\"font-semibold text-[var(--color-text-primary)] truncate\">\n {invite.organization?.name ?? tr('common.organization', 'Organization')}\n </h3>\n <div className=\"flex items-center gap-2 mt-1\">\n <MemberRoleBadge role={invite.role} />\n <span className=\"text-xs text-[var(--color-text-muted)] flex items-center gap-1\">\n <Clock size={12} />\n {daysUntilExpiry > 0\n ? `${tr('members.myInvites.expiresIn', 'Expires in')} ${daysUntilExpiry}d`\n : tr('members.myInvites.expiringSoon', 'Expiring soon')}\n </span>\n </div>\n {invite.message && (\n <p className=\"mt-2 text-sm text-[var(--color-text-secondary)] italic\">\n &ldquo;{invite.message}&rdquo;\n </p>\n )}\n </div>\n </div>\n\n {/* Right: Actions */}\n <div className=\"flex flex-wrap items-center gap-2 shrink-0\">\n <button\n type=\"button\"\n onClick={() => onAccept(invite.id)}\n disabled={accepting || rejecting}\n className=\"\n inline-flex items-center gap-1.5 px-4 py-2\n bg-[var(--color-status-success-bg)] text-[var(--color-text-inverse)] rounded-lg\n hover:opacity-90\n \n transition-all duration-200\n text-sm font-medium\n disabled:opacity-50 disabled:cursor-not-allowed\n \"\n >\n {accepting ? <Loader2 size={14} className=\"animate-spin\" /> : <Check size={14} />}\n {tr('members.myInvites.accept', 'Accept')}\n </button>\n <button\n type=\"button\"\n onClick={() => onReject(invite.id)}\n disabled={accepting || rejecting}\n className=\"\n inline-flex items-center gap-1.5 px-4 py-2\n bg-transparent text-[var(--color-text-primary)]\n border border-[var(--color-border-default)]\n rounded-lg\n hover:bg-[var(--color-status-error-bgSubtle)] hover:border-[var(--color-status-error-border)] hover:text-[var(--color-status-error-text)]\n \n transition-all duration-200\n text-sm font-medium\n disabled:opacity-50 disabled:cursor-not-allowed\n \"\n >\n {rejecting ? <Loader2 size={14} className=\"animate-spin\" /> : <X size={14} />}\n {tr('members.myInvites.decline', 'Decline')}\n </button>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;AAwBA,SAAgB,EAAa,EAC3B,WACA,aACA,aACA,cACA,gBACoB;CACpB,IAAM,IAAK,GAAO,EACZ,IAAkB,KAAK,IAC3B,GACA,KAAK,MAAM,IAAI,KAAK,EAAO,UAAU,CAAC,SAAS,GAAG,KAAK,KAAK,KAAK,MAAO,KAAK,KAAK,IAAI,CACvF;AAED,QACE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD;GAAK,WAAU;aAAf,CAEE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,GAAD;MAAW,MAAM;MAAI,WAAU;MAAuC,CAAA;KAClE,CAAA,EACN,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAO,cAAc,QAAQ,EAAG,uBAAuB,eAAe;OACpE,CAAA;MACL,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAiB,MAAM,EAAO,MAAQ,CAAA,EACtC,kBAAC,QAAD;QAAM,WAAU;kBAAhB,CACE,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA,EAClB,IAAkB,IACf,GAAG,EAAG,+BAA+B,aAAa,CAAC,GAAG,EAAgB,KACtE,EAAG,kCAAkC,gBAAgB,CACpD;UACH;;MACL,EAAO,WACN,kBAAC,KAAD;OAAG,WAAU;iBAAb;QAAsE;QAC5D,EAAO;QAAQ;QACrB;;MAEF;OACF;OAGN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,UAAD;KACE,MAAK;KACL,eAAe,EAAS,EAAO,GAAG;KAClC,UAAU,KAAa;KACvB,WAAU;eAJZ,CAcG,IAAY,kBAAC,GAAD;MAAS,MAAM;MAAI,WAAU;MAAiB,CAAA,GAAG,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA,EAChF,EAAG,4BAA4B,SAAS,CAClC;QACT,kBAAC,UAAD;KACE,MAAK;KACL,eAAe,EAAS,EAAO,GAAG;KAClC,UAAU,KAAa;KACvB,WAAU;eAJZ,CAgBG,IAAY,kBAAC,GAAD;MAAS,MAAM;MAAI,WAAU;MAAiB,CAAA,GAAG,kBAAC,GAAD,EAAG,MAAM,IAAM,CAAA,EAC5E,EAAG,6BAA6B,UAAU,CACpC;OACL;MACF;;EACF,CAAA"}
1
+ {"version":3,"file":"MyInviteCard.js","names":["MyInviteCard","tr","useTr","daysUntilExpiry","invite","Building2","MemberRoleBadge","Clock","onAccept","accepting","rejecting","Loader2","Check","onReject","X"],"sources":["../../../../../src/organization-management/modules/members/components/MyInviteCard.tsx"],"sourcesContent":["import { Check, X, Building2, Clock, Loader2 } from 'lucide-react';\nimport { MemberRoleBadge } from './MemberRoleBadge';\nimport { useTr } from '../../../shared/hooks/useTr';\n\ninterface MyInviteCardProps {\n invite: {\n id: string;\n email: string;\n role: string;\n expiresAt: string;\n message?: string | null;\n createdAt: string;\n organization?: {\n id: string;\n name: string;\n slug: string;\n } | null;\n };\n onAccept: (inviteId: string) => Promise<void>;\n onReject: (inviteId: string) => Promise<void>;\n accepting?: boolean;\n rejecting?: boolean;\n}\n\nexport function MyInviteCard({\n invite,\n onAccept,\n onReject,\n accepting,\n rejecting,\n}: MyInviteCardProps) {\n const tr = useTr();\n const daysUntilExpiry = Math.max(\n 0,\n Math.ceil((new Date(invite.expiresAt).getTime() - Date.now()) / (1000 * 60 * 60 * 24))\n );\n\n return (\n <div className=\"rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] p-5 transition-colors hover:border-[var(--color-border-focus)]\">\n <div className=\"flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between\">\n {/* Left: Org info */}\n <div className=\"flex items-start gap-3 min-w-0\">\n <div className=\"p-2 rounded-lg bg-[var(--color-bg-subtle)]\">\n <Building2 size={20} className=\"text-[var(--color-text-secondary)]\" />\n </div>\n <div className=\"min-w-0\">\n <h3 className=\"font-semibold text-[var(--color-text-primary)] truncate\">\n {invite.organization?.name ?? tr('common.organization', 'Organization')}\n </h3>\n <div className=\"flex items-center gap-2 mt-1\">\n <MemberRoleBadge role={invite.role} />\n <span className=\"text-xs text-[var(--color-text-muted)] flex items-center gap-1\">\n <Clock size={12} />\n {daysUntilExpiry > 0\n ? `${tr('members.myInvites.expiresIn', 'Expires in')} ${daysUntilExpiry}d`\n : tr('members.myInvites.expiringSoon', 'Expiring soon')}\n </span>\n </div>\n {invite.message && (\n <p className=\"mt-2 text-sm text-[var(--color-text-secondary)] italic\">\n &ldquo;{invite.message}&rdquo;\n </p>\n )}\n </div>\n </div>\n\n {/* Right: Actions */}\n <div className=\"flex flex-wrap items-center gap-2 shrink-0\">\n <button\n type=\"button\"\n onClick={() => onAccept(invite.id)}\n disabled={accepting || rejecting}\n className=\"\n inline-flex items-center gap-1.5 px-4 py-2\n bg-[var(--color-status-success-bg)] text-[var(--color-text-inverse)] rounded-lg\n hover:opacity-90\n \n transition-all duration-200\n text-sm font-medium\n disabled:opacity-50 disabled:cursor-not-allowed\n \"\n >\n {accepting ? <Loader2 size={14} className=\"animate-spin\" /> : <Check size={14} />}\n {tr('members.myInvites.accept', 'Accept')}\n </button>\n <button\n type=\"button\"\n onClick={() => onReject(invite.id)}\n disabled={accepting || rejecting}\n className=\"\n inline-flex items-center gap-1.5 px-4 py-2\n bg-transparent text-[var(--color-text-primary)]\n border border-[var(--color-border-default)]\n rounded-lg\n hover:bg-[var(--color-status-error-bgSubtle)] hover:border-[var(--color-status-error-border)] hover:text-[var(--color-status-error-text)]\n \n transition-all duration-200\n text-sm font-medium\n disabled:opacity-50 disabled:cursor-not-allowed\n \"\n >\n {rejecting ? <Loader2 size={14} className=\"animate-spin\" /> : <X size={14} />}\n {tr('members.myInvites.decline', 'Decline')}\n </button>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;AAwBA,SAAgBA,EAAa,EAC3B,WACA,aACA,aACA,cACA,gBACoB;CACpB,IAAMC,IAAKC,EAAM,GACXC,IAAkB,KAAK,IAC3B,GACA,KAAK,MAAM,IAAI,KAAKC,EAAO,SAAS,CAAC,CAAC,QAAQ,IAAI,KAAK,IAAI,KAAM,KAAoB,CACvF;CAEA,OACE,kBAAC,OAAD;EAAK,WAAU;EACb,UAAA,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CAEE,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,kBAAC,OAAD;KAAK,WAAU;KACb,UAAA,kBAACC,GAAD;MAAW,MAAM;MAAI,WAAU;KAAsC,CAAA;IAClE,CAAA,GACL,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA;MACE,kBAAC,MAAD;OAAI,WAAU;OACX,UAAAD,EAAO,cAAc,QAAQH,EAAG,uBAAuB,cAAc;MACpE,CAAA;MACJ,kBAAC,OAAD;OAAK,WAAU;OAAf,UAAA,CACE,kBAACK,GAAD,EAAiB,MAAMF,EAAO,KAAO,CAAA,GACrC,kBAAC,QAAD;QAAM,WAAU;QAAhB,UAAA,CACE,kBAACG,GAAD,EAAO,MAAM,GAAK,CAAA,GACjBJ,IAAkB,IACf,GAAGF,EAAG,+BAA+B,YAAY,EAAE,GAAGE,EAAgB,KACtEF,EAAG,kCAAkC,eAAe,CACpD;OACH,CAAA,CAAA;;MACJG,EAAO,WACN,kBAAC,KAAD;OAAG,WAAU;OAAb,UAAA;QAAsE;QAC5DA,EAAO;QAAQ;OACtB;;KAEF;IACF,CAAA,CAAA;GAGL,CAAA,GAAA,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,kBAAC,UAAD;KACE,MAAK;KACL,eAAeI,EAASJ,EAAO,EAAE;KACjC,UAAUK,KAAaC;KACvB,WAAU;KAJZ,UAAA,CAcGD,IAAY,kBAACE,GAAD;MAAS,MAAM;MAAI,WAAU;KAAgB,CAAA,IAAI,kBAACC,GAAD,EAAO,MAAM,GAAK,CAAA,GAC/EX,EAAG,4BAA4B,QAAQ,CAClC;IACR,CAAA,GAAA,kBAAC,UAAD;KACE,MAAK;KACL,eAAeY,EAAST,EAAO,EAAE;KACjC,UAAUK,KAAaC;KACvB,WAAU;KAJZ,UAAA,CAgBGA,IAAY,kBAACC,GAAD;MAAS,MAAM;MAAI,WAAU;KAAgB,CAAA,IAAI,kBAACG,GAAD,EAAG,MAAM,GAAK,CAAA,GAC3Eb,EAAG,6BAA6B,SAAS,CACpC;IACL,CAAA,CAAA;GACF,CAAA,CAAA;;CACF,CAAA;AAET"}
@@ -1,16 +1,16 @@
1
1
  import { toast as e } from "../../../../node_modules/sonner/dist/index.js";
2
2
  import { useCancelInvite as t, useOrganizationInvites as n, useResendInvite as r } from "../hooks/useInvites.js";
3
- import { InviteStatus as i } from "../../../../generated/global-types.js";
4
- import { useTr as a } from "../../../shared/hooks/useTr.js";
5
- import { InviteStatusBadge as o } from "./InviteStatusBadge.js";
6
- import { MemberRoleBadge as s } from "./MemberRoleBadge.js";
3
+ import { InviteStatusBadge as i } from "./InviteStatusBadge.js";
4
+ import { MemberRoleBadge as a } from "./MemberRoleBadge.js";
5
+ import { InviteStatus as o } from "../../../../generated/global-types.js";
6
+ import { useTr as s } from "../../../shared/hooks/useTr.js";
7
7
  import { useState as c } from "react";
8
8
  import { AlertCircle as l, Loader2 as u, RotateCw as d, X as f } from "lucide-react";
9
9
  import { ResponsiveTable as p } from "@burdenoff/fe-libs/ui";
10
10
  import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
11
- //#region src/organization-management/modules/members/components/PendingInvitesList.tsx
11
+ // src/organization-management/modules/members/components/PendingInvitesList.tsx
12
12
  function _({ organizationId: _ }) {
13
- let v = a(), { invites: y, loading: b, error: x, total: S } = n(_, { status: i.Pending }, 50), { cancelInvite: C, loading: w } = t(), { resendInvite: T, loading: E } = r(), [D, O] = c(null);
13
+ let v = s(), { invites: y, loading: b, error: x, total: S } = n(_, { status: o.Pending }, 50), { cancelInvite: C, loading: w } = t(), { resendInvite: T, loading: E } = r(), [D, O] = c(null);
14
14
  if (b && y.length === 0) return /* @__PURE__ */ h("div", {
15
15
  className: "flex items-center justify-center py-8",
16
16
  children: /* @__PURE__ */ h(u, {
@@ -57,12 +57,12 @@ function _({ organizationId: _ }) {
57
57
  {
58
58
  key: "role",
59
59
  header: v("members.list.column.role", "Role"),
60
- cell: (e) => /* @__PURE__ */ h(s, { role: e.role })
60
+ cell: (e) => /* @__PURE__ */ h(a, { role: e.role })
61
61
  },
62
62
  {
63
63
  key: "status",
64
64
  header: v("common.status", "Status"),
65
- cell: (e) => /* @__PURE__ */ h(o, { status: e.status })
65
+ cell: (e) => /* @__PURE__ */ h(i, { status: e.status })
66
66
  },
67
67
  {
68
68
  key: "expires",
@@ -117,7 +117,6 @@ function _({ organizationId: _ }) {
117
117
  })
118
118
  ] });
119
119
  }
120
- //#endregion
121
120
  export { _ as PendingInvitesList };
122
121
 
123
122
  //# sourceMappingURL=PendingInvitesList.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PendingInvitesList.js","names":[],"sources":["../../../../../src/organization-management/modules/members/components/PendingInvitesList.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { RotateCw, X, Loader2, AlertCircle } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { ResponsiveTable, type ResponsiveTableColumn } from '@burdenoff/fe-libs/ui';\nimport { useOrganizationInvites, useCancelInvite, useResendInvite } from '../hooks/useInvites';\nimport { InviteStatusBadge } from './InviteStatusBadge';\nimport { MemberRoleBadge } from './MemberRoleBadge';\nimport { InviteStatus } from '../../../../generated/global-types';\nimport type { OrganizationInvite } from '../../../../generated/global-types';\nimport { useTr } from '../../../shared/hooks/useTr';\n\ninterface PendingInvitesListProps {\n organizationId: string;\n}\n\nexport function PendingInvitesList({ organizationId }: PendingInvitesListProps) {\n const tr = useTr();\n const { invites, loading, error, total } = useOrganizationInvites(\n organizationId,\n { status: InviteStatus.Pending },\n 50\n );\n const { cancelInvite, loading: cancelling } = useCancelInvite();\n const { resendInvite, loading: resending } = useResendInvite();\n const [actionError, setActionError] = useState<string | null>(null);\n\n if (loading && invites.length === 0) {\n return (\n <div className=\"flex items-center justify-center py-8\">\n <Loader2 size={20} className=\"animate-spin text-[var(--color-text-muted)]\" />\n </div>\n );\n }\n\n if (error) {\n return (\n <p className=\"py-6 text-center text-sm text-[var(--color-status-error-text)]\">\n {tr('members.myInvites.loadFailed', 'Failed to load invites')}: {error.message}\n </p>\n );\n }\n\n if (invites.length === 0) {\n return (\n <p className=\"text-sm text-[var(--color-text-muted)] text-center py-6\">\n {tr('members.myInvites.emptyTitle', 'No pending invites')}\n </p>\n );\n }\n\n const handleCancel = async (inviteId: string, email: string) => {\n try {\n setActionError(null);\n await cancelInvite(inviteId);\n toast.success(`${tr('members.invite.cancelSuccess', 'Invite cancelled for')} ${email}`);\n } catch (err) {\n const msg =\n err instanceof Error\n ? err.message\n : tr('members.invite.cancelFailed', 'Failed to cancel invite');\n setActionError(msg);\n toast.error(msg);\n }\n };\n\n const handleResend = async (inviteId: string, email: string) => {\n try {\n setActionError(null);\n await resendInvite(inviteId);\n toast.success(`${tr('members.invite.resendSuccess', 'Invite re-sent to')} ${email}`);\n } catch (err) {\n const msg =\n err instanceof Error\n ? err.message\n : tr('members.invite.resendFailed', 'Failed to resend invite');\n setActionError(msg);\n toast.error(msg);\n }\n };\n\n const columns: ResponsiveTableColumn<OrganizationInvite>[] = [\n {\n key: 'email',\n header: tr('members.invite.emailLabel', 'Email Address'),\n priority: 'primary',\n cell: (invite) => <span className=\"text-[var(--color-text-primary)]\">{invite.email}</span>,\n },\n {\n key: 'role',\n header: tr('members.list.column.role', 'Role'),\n cell: (invite) => <MemberRoleBadge role={invite.role} />,\n },\n {\n key: 'status',\n header: tr('common.status', 'Status'),\n cell: (invite) => <InviteStatusBadge status={invite.status} />,\n },\n {\n key: 'expires',\n header: tr('members.invite.expires', 'Expires'),\n cell: (invite) => (\n <span className=\"text-[var(--color-text-muted)]\">\n {new Date(invite.expiresAt).toLocaleDateString()}\n </span>\n ),\n },\n ];\n\n return (\n <div>\n <h3 className=\"text-sm font-semibold text-[var(--color-text-secondary)] uppercase tracking-wider mb-3\">\n {tr('members.invite.pendingTitle', 'Pending Invites')} ({total})\n </h3>\n\n {actionError && (\n <div className=\"mb-3 flex items-center gap-2 rounded-lg border border-[var(--color-status-error-border)] bg-[var(--color-status-error-bgSubtle)] p-2.5\">\n <AlertCircle size={14} className=\"shrink-0 text-[var(--color-status-error-text)]\" />\n <p className=\"text-sm text-[var(--color-status-error-text)]\">{actionError}</p>\n </div>\n )}\n\n <ResponsiveTable<OrganizationInvite>\n columns={columns}\n data={invites}\n rowKey={(invite) => invite.id}\n rowActions={(invite) => (\n <>\n <button\n type=\"button\"\n onClick={() => handleResend(invite.id, invite.email)}\n disabled={resending}\n className=\"p-1.5 rounded-md hover:bg-[var(--color-bg-subtle)] text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)] transition-colors\"\n title={tr('members.invite.resend', 'Resend invite')}\n aria-label={`${tr('members.invite.resendFor', 'Resend invite for')} ${invite.email}`}\n >\n <RotateCw size={14} />\n </button>\n <button\n type=\"button\"\n onClick={() => handleCancel(invite.id, invite.email)}\n disabled={cancelling}\n className=\"p-1.5 rounded-md text-[var(--color-text-muted)] transition-colors hover:bg-[var(--color-status-error-bgSubtle)] hover:text-[var(--color-status-error-text)]\"\n title={tr('members.invite.cancel', 'Cancel invite')}\n aria-label={`${tr('members.invite.cancelFor', 'Cancel invite for')} ${invite.email}`}\n >\n <X size={14} />\n </button>\n </>\n )}\n />\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"PendingInvitesList.js","names":["_Fragment","PendingInvitesList","tr","useTr","useOrganizationInvites","organizationId","InviteStatus","cancelling","useCancelInvite","resending","useResendInvite","actionError","setActionError","useState","loading","invites","Loader2","error","handleCancel","cancelInvite","inviteId","toast","email","err","msg","handleResend","resendInvite","columns","invite","MemberRoleBadge","InviteStatusBadge","total","AlertCircle","ResponsiveTable","Fragment","RotateCw","X"],"sources":["../../../../../src/organization-management/modules/members/components/PendingInvitesList.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { RotateCw, X, Loader2, AlertCircle } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { ResponsiveTable, type ResponsiveTableColumn } from '@burdenoff/fe-libs/ui';\nimport { useOrganizationInvites, useCancelInvite, useResendInvite } from '../hooks/useInvites';\nimport { InviteStatusBadge } from './InviteStatusBadge';\nimport { MemberRoleBadge } from './MemberRoleBadge';\nimport { InviteStatus } from '../../../../generated/global-types';\nimport type { OrganizationInvite } from '../../../../generated/global-types';\nimport { useTr } from '../../../shared/hooks/useTr';\n\ninterface PendingInvitesListProps {\n organizationId: string;\n}\n\nexport function PendingInvitesList({ organizationId }: PendingInvitesListProps) {\n const tr = useTr();\n const { invites, loading, error, total } = useOrganizationInvites(\n organizationId,\n { status: InviteStatus.Pending },\n 50\n );\n const { cancelInvite, loading: cancelling } = useCancelInvite();\n const { resendInvite, loading: resending } = useResendInvite();\n const [actionError, setActionError] = useState<string | null>(null);\n\n if (loading && invites.length === 0) {\n return (\n <div className=\"flex items-center justify-center py-8\">\n <Loader2 size={20} className=\"animate-spin text-[var(--color-text-muted)]\" />\n </div>\n );\n }\n\n if (error) {\n return (\n <p className=\"py-6 text-center text-sm text-[var(--color-status-error-text)]\">\n {tr('members.myInvites.loadFailed', 'Failed to load invites')}: {error.message}\n </p>\n );\n }\n\n if (invites.length === 0) {\n return (\n <p className=\"text-sm text-[var(--color-text-muted)] text-center py-6\">\n {tr('members.myInvites.emptyTitle', 'No pending invites')}\n </p>\n );\n }\n\n const handleCancel = async (inviteId: string, email: string) => {\n try {\n setActionError(null);\n await cancelInvite(inviteId);\n toast.success(`${tr('members.invite.cancelSuccess', 'Invite cancelled for')} ${email}`);\n } catch (err) {\n const msg =\n err instanceof Error\n ? err.message\n : tr('members.invite.cancelFailed', 'Failed to cancel invite');\n setActionError(msg);\n toast.error(msg);\n }\n };\n\n const handleResend = async (inviteId: string, email: string) => {\n try {\n setActionError(null);\n await resendInvite(inviteId);\n toast.success(`${tr('members.invite.resendSuccess', 'Invite re-sent to')} ${email}`);\n } catch (err) {\n const msg =\n err instanceof Error\n ? err.message\n : tr('members.invite.resendFailed', 'Failed to resend invite');\n setActionError(msg);\n toast.error(msg);\n }\n };\n\n const columns: ResponsiveTableColumn<OrganizationInvite>[] = [\n {\n key: 'email',\n header: tr('members.invite.emailLabel', 'Email Address'),\n priority: 'primary',\n cell: (invite) => <span className=\"text-[var(--color-text-primary)]\">{invite.email}</span>,\n },\n {\n key: 'role',\n header: tr('members.list.column.role', 'Role'),\n cell: (invite) => <MemberRoleBadge role={invite.role} />,\n },\n {\n key: 'status',\n header: tr('common.status', 'Status'),\n cell: (invite) => <InviteStatusBadge status={invite.status} />,\n },\n {\n key: 'expires',\n header: tr('members.invite.expires', 'Expires'),\n cell: (invite) => (\n <span className=\"text-[var(--color-text-muted)]\">\n {new Date(invite.expiresAt).toLocaleDateString()}\n </span>\n ),\n },\n ];\n\n return (\n <div>\n <h3 className=\"text-sm font-semibold text-[var(--color-text-secondary)] uppercase tracking-wider mb-3\">\n {tr('members.invite.pendingTitle', 'Pending Invites')} ({total})\n </h3>\n\n {actionError && (\n <div className=\"mb-3 flex items-center gap-2 rounded-lg border border-[var(--color-status-error-border)] bg-[var(--color-status-error-bgSubtle)] p-2.5\">\n <AlertCircle size={14} className=\"shrink-0 text-[var(--color-status-error-text)]\" />\n <p className=\"text-sm text-[var(--color-status-error-text)]\">{actionError}</p>\n </div>\n )}\n\n <ResponsiveTable<OrganizationInvite>\n columns={columns}\n data={invites}\n rowKey={(invite) => invite.id}\n rowActions={(invite) => (\n <>\n <button\n type=\"button\"\n onClick={() => handleResend(invite.id, invite.email)}\n disabled={resending}\n className=\"p-1.5 rounded-md hover:bg-[var(--color-bg-subtle)] text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)] transition-colors\"\n title={tr('members.invite.resend', 'Resend invite')}\n aria-label={`${tr('members.invite.resendFor', 'Resend invite for')} ${invite.email}`}\n >\n <RotateCw size={14} />\n </button>\n <button\n type=\"button\"\n onClick={() => handleCancel(invite.id, invite.email)}\n disabled={cancelling}\n className=\"p-1.5 rounded-md text-[var(--color-text-muted)] transition-colors hover:bg-[var(--color-status-error-bgSubtle)] hover:text-[var(--color-status-error-text)]\"\n title={tr('members.invite.cancel', 'Cancel invite')}\n aria-label={`${tr('members.invite.cancelFor', 'Cancel invite for')} ${invite.email}`}\n >\n <X size={14} />\n </button>\n </>\n )}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;AAeA,SAAgBC,EAAmB,EAAE,qBAA2C;CAC9E,IAAMC,IAAKC,EAAM,GACX,EAAE,YAAS,YAAS,UAAO,aAAUC,EACzCC,GACA,EAAE,QAAQC,EAAa,QAAQ,GAC/B,EACF,GACM,EAAE,iBAAc,SAASC,MAAeC,EAAgB,GACxD,EAAE,iBAAc,SAASC,MAAcC,EAAgB,GACvD,CAACC,GAAaC,KAAkBC,EAAwB,IAAI;CAElE,IAAIC,KAAWC,EAAQ,WAAW,GAChC,OACE,kBAAC,OAAD;EAAK,WAAU;EACb,UAAA,kBAACC,GAAD;GAAS,MAAM;GAAI,WAAU;EAA+C,CAAA;CACzE,CAAA;CAIT,IAAIC,GACF,OACE,kBAAC,KAAD;EAAG,WAAU;EAAb,UAAA;GACGf,EAAG,gCAAgC,wBAAwB;GAAE;GAAGe,EAAM;EACtE;;CAIP,IAAIF,EAAQ,WAAW,GACrB,OACE,kBAAC,KAAD;EAAG,WAAU;EACV,UAAAb,EAAG,gCAAgC,oBAAoB;CACvD,CAAA;CAIP,IAAMgB,IAAe,OAAO,GAAkB,MAAkB;EAC9D,IAAI;GAGF,AAFAN,EAAe,IAAI,GACnB,MAAMO,EAAaC,CAAQ,GAC3BC,EAAM,QAAQ,GAAGnB,EAAG,gCAAgC,sBAAsB,EAAE,GAAGoB,GAAO;EACxF,SAASC,GAAK;GACZ,IAAMC,IACJD,aAAe,QACXA,EAAI,UACJrB,EAAG,+BAA+B,yBAAyB;GAEjE,AADAU,EAAeY,CAAG,GAClBH,EAAM,MAAMG,CAAG;EACjB;CACF,GAEMC,IAAe,OAAO,GAAkB,MAAkB;EAC9D,IAAI;GAGF,AAFAb,EAAe,IAAI,GACnB,MAAMc,EAAaN,CAAQ,GAC3BC,EAAM,QAAQ,GAAGnB,EAAG,gCAAgC,mBAAmB,EAAE,GAAGoB,GAAO;EACrF,SAASC,GAAK;GACZ,IAAMC,IACJD,aAAe,QACXA,EAAI,UACJrB,EAAG,+BAA+B,yBAAyB;GAEjE,AADAU,EAAeY,CAAG,GAClBH,EAAM,MAAMG,CAAG;EACjB;CACF,GAEMG,IAAuD;EAC3D;GACE,KAAK;GACL,QAAQzB,EAAG,6BAA6B,eAAe;GACvD,UAAU;GACV,OAAO,MAAW,kBAAC,QAAD;IAAM,WAAU;IAAoC,UAAA0B,EAAO;GAAY,CAAA;EAC3F;EACA;GACE,KAAK;GACL,QAAQ1B,EAAG,4BAA4B,MAAM;GAC7C,OAAO,MAAW,kBAAC2B,GAAD,EAAiB,MAAMD,EAAO,KAAO,CAAA;EACzD;EACA;GACE,KAAK;GACL,QAAQ1B,EAAG,iBAAiB,QAAQ;GACpC,OAAO,MAAW,kBAAC4B,GAAD,EAAmB,QAAQF,EAAO,OAAS,CAAA;EAC/D;EACA;GACE,KAAK;GACL,QAAQ1B,EAAG,0BAA0B,SAAS;GAC9C,OAAO,MACL,kBAAC,QAAD;IAAM,WAAU;IACb,UAAA,IAAI,KAAK0B,EAAO,SAAS,CAAC,CAAC,mBAAmB;GAC3C,CAAA;EAEV;CACF;CAEA,OACE,kBAAC,OAAD,EAAA,UAAA;EACE,kBAAC,MAAD;GAAI,WAAU;GAAd,UAAA;IACG1B,EAAG,+BAA+B,iBAAiB;IAAE;IAAG6B;IAAM;GAC7D;;EAEHpB,KACC,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,kBAACqB,GAAD;IAAa,MAAM;IAAI,WAAU;GAAkD,CAAA,GACnF,kBAAC,KAAD;IAAG,WAAU;IAAiD,UAAArB;GAAe,CAAA,CAC1E;;EAGP,kBAACsB,GAAD;GACW;GACT,MAAMlB;GACN,SAAS,MAAWa,EAAO;GAC3B,aAAa,MACX,kBAAA5B,GAAA,EAAA,UAAA,CACE,kBAAC,UAAD;IACE,MAAK;IACL,eAAeyB,EAAaG,EAAO,IAAIA,EAAO,KAAK;IACnD,UAAUnB;IACV,WAAU;IACV,OAAOP,EAAG,yBAAyB,eAAe;IAClD,cAAY,GAAGA,EAAG,4BAA4B,mBAAmB,EAAE,GAAG0B,EAAO;IAE7E,UAAA,kBAACO,GAAD,EAAU,MAAM,GAAK,CAAA;GACf,CAAA,GACR,kBAAC,UAAD;IACE,MAAK;IACL,eAAejB,EAAaU,EAAO,IAAIA,EAAO,KAAK;IACnD,UAAUrB;IACV,WAAU;IACV,OAAOL,EAAG,yBAAyB,eAAe;IAClD,cAAY,GAAGA,EAAG,4BAA4B,mBAAmB,EAAE,GAAG0B,EAAO;IAE7E,UAAA,kBAACQ,GAAD,EAAG,MAAM,GAAK,CAAA;GACR,CAAA,CACR,EAAA,CAAA;EAEL,CAAA;CACE,EAAA,CAAA;AAET"}
@@ -4,7 +4,7 @@ import { logger as d, redactId as f } from "../../../shared/logger.js";
4
4
  import { executeRecaptcha as p } from "../../../shared/recaptcha.js";
5
5
  import { gql as m } from "@apollo/client";
6
6
  import { useMutation as h } from "@apollo/client/react";
7
- //#region src/organization-management/modules/members/hooks/useInvites.ts
7
+ // src/organization-management/modules/members/hooks/useInvites.ts
8
8
  var g = m`
9
9
  mutation AcceptOrganizationInviteWithCaptcha($inviteId: ID!, $recaptchaToken: String) {
10
10
  acceptOrganizationInvite(inviteId: $inviteId, recaptchaToken: $recaptchaToken) {
@@ -124,7 +124,7 @@ function C() {
124
124
  inviteId: f(e)
125
125
  });
126
126
  try {
127
- let t = await p("invite_accept"), i = await r({ variables: {
127
+ let t = await /* @__PURE__ */ p("invite_accept"), i = await r({ variables: {
128
128
  inviteId: e,
129
129
  ...t ? { recaptchaToken: t } : {}
130
130
  } });
@@ -262,7 +262,6 @@ function E() {
262
262
  error: i
263
263
  };
264
264
  }
265
- //#endregion
266
265
  export { C as useAcceptInvite, T as useCancelInvite, S as useInviteMember, b as useMyInvites, x as useOrganizationInvite, y as useOrganizationInvites, w as useRejectInvite, E as useResendInvite };
267
266
 
268
267
  //# sourceMappingURL=useInvites.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useInvites.js","names":[],"sources":["../../../../../src/organization-management/modules/members/hooks/useInvites.ts"],"sourcesContent":["import { gql } from '@apollo/client';\nimport { useMutation } from '@apollo/client/react';\nimport {\n useInviteOrganizationMemberMutation,\n useRejectOrganizationInviteMutation,\n useCancelOrganizationInviteMutation,\n useResendOrganizationInviteMutation,\n useGetOrganizationInvitesQuery,\n useGetMyOrganizationInvitesQuery,\n useGetMyOrganizationInviteQuery,\n GetOrganizationInvitesDocument,\n GetMyOrganizationInvitesDocument,\n GetMembersDocument,\n} from '../../../../generated/global-operations';\nimport type {\n InviteStatus,\n OrganizationInvite,\n OrganizationMember,\n} from '../../../../generated/global-types';\nimport { useOrganizationEventEmitter } from '../../../hooks/useOrganizationEventEmitter';\nimport { logger, redactId } from '../../../shared/logger';\nimport { executeRecaptcha } from '../../../shared/recaptcha';\n\nconst ACCEPT_ORGANIZATION_INVITE_WITH_CAPTCHA = gql`\n mutation AcceptOrganizationInviteWithCaptcha($inviteId: ID!, $recaptchaToken: String) {\n acceptOrganizationInvite(inviteId: $inviteId, recaptchaToken: $recaptchaToken) {\n id\n userId\n organizationId\n role\n joinedAt\n }\n }\n`;\n\ninterface AcceptOrganizationInviteData {\n acceptOrganizationInvite: OrganizationMember;\n}\n\ninterface AcceptOrganizationInviteVariables {\n inviteId: string;\n recaptchaToken?: string;\n}\n\ninterface GraphqlExtensions {\n code?: string;\n}\n\ninterface GraphqlError {\n message?: string;\n extensions?: GraphqlExtensions;\n}\n\ninterface ApolloLikeError {\n message?: string;\n graphQLErrors?: ReadonlyArray<GraphqlError>;\n}\n\nfunction extractErrorCode(error: unknown): string | undefined {\n const apolloError = error as ApolloLikeError | undefined;\n return apolloError?.graphQLErrors?.[0]?.extensions?.code;\n}\n\nfunction extractErrorMessage(error: unknown): string {\n if (error instanceof Error) return error.message;\n const apolloError = error as ApolloLikeError | undefined;\n return apolloError?.message ?? 'Unknown error';\n}\n\n/**\n * Hook to fetch organization invites (admin view)\n */\nexport function useOrganizationInvites(\n organizationId: string,\n filter?: { status?: InviteStatus },\n limit: number = 20,\n offset: number = 0\n) {\n const { data, loading, error, refetch } = useGetOrganizationInvitesQuery({\n variables: { organizationId, filter, limit, offset },\n skip: !organizationId,\n fetchPolicy: 'cache-first',\n nextFetchPolicy: 'cache-first',\n });\n\n return {\n invites: (data?.organizationInvites?.items ?? []) as OrganizationInvite[],\n total: data?.organizationInvites?.total ?? 0,\n hasMore: data?.organizationInvites?.hasMore ?? false,\n loading,\n error,\n refetch,\n };\n}\n\n/**\n * Hook to fetch invites for the current user (invitee view).\n *\n * `enabled` defaults to `true` for backward compat. Callers in admin /\n * service contexts (e.g. OrganizationsListPage in `mode=\"admin\"`) should\n * pass `false` to skip the network round-trip and avoid surfacing\n * authorization errors for actors that don't hold the self-scope.\n */\nexport function useMyInvites(\n status?: InviteStatus,\n limit: number = 20,\n offset: number = 0,\n enabled: boolean = true\n) {\n const { data, loading, error, refetch } = useGetMyOrganizationInvitesQuery({\n variables: { status, limit, offset },\n skip: !enabled,\n fetchPolicy: 'cache-first',\n nextFetchPolicy: 'cache-first',\n });\n\n return {\n invites: (data?.myOrganizationInvites?.items ?? []) as OrganizationInvite[],\n total: data?.myOrganizationInvites?.total ?? 0,\n hasMore: data?.myOrganizationInvites?.hasMore ?? false,\n loading,\n error,\n refetch,\n };\n}\n\n/**\n * Hook to fetch a SINGLE invite addressed to the current user, by id.\n * Backs the per-invite acceptance page reached from the invite email link.\n * `enabled` defaults to true; pass false to defer until the user is\n * authenticated (the query is self-scoped and 401s for anonymous callers).\n */\nexport function useOrganizationInvite(inviteId: string, enabled: boolean = true) {\n const { data, loading, error, refetch } = useGetMyOrganizationInviteQuery({\n variables: { id: inviteId },\n skip: !enabled || !inviteId,\n fetchPolicy: 'network-only',\n nextFetchPolicy: 'cache-first',\n });\n\n return {\n invite: (data?.myOrganizationInvite ?? null) as OrganizationInvite | null,\n loading,\n error,\n refetch,\n };\n}\n\n/**\n * Hook to invite a member by email\n */\nexport function useInviteMember() {\n const { emit } = useOrganizationEventEmitter();\n const [inviteMember, { loading, error }] = useInviteOrganizationMemberMutation({\n refetchQueries: [GetOrganizationInvitesDocument],\n });\n\n return {\n inviteMember: async (input: { organizationId: string; email: string; message?: string }) => {\n logger.info('mutation.start', {\n name: 'inviteMember',\n organizationId: redactId(input.organizationId),\n });\n try {\n const result = await inviteMember({ variables: { input } });\n const inviteId = result.data?.inviteOrganizationMember?.id;\n emit('organization.invite.created', {\n organizationId: input.organizationId,\n inviteId,\n source: 'microfe-organization',\n });\n logger.info('mutation.success', {\n name: 'inviteMember',\n organizationId: redactId(input.organizationId),\n inviteId: redactId(inviteId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('organization.invite.create_failed', {\n organizationId: input.organizationId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'inviteMember',\n organizationId: redactId(input.organizationId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n\n/**\n * Hook to accept an organization invite\n */\nexport function useAcceptInvite() {\n const { emit } = useOrganizationEventEmitter();\n const [acceptInvite, { loading, error }] = useMutation<\n AcceptOrganizationInviteData,\n AcceptOrganizationInviteVariables\n >(ACCEPT_ORGANIZATION_INVITE_WITH_CAPTCHA, {\n refetchQueries: [GetMyOrganizationInvitesDocument, GetMembersDocument],\n });\n\n return {\n acceptInvite: async (inviteId: string) => {\n logger.info('mutation.start', {\n name: 'acceptInvite',\n inviteId: redactId(inviteId),\n });\n try {\n const recaptchaToken = await executeRecaptcha('invite_accept');\n const result = await acceptInvite({\n variables: { inviteId, ...(recaptchaToken ? { recaptchaToken } : {}) },\n });\n emit('organization.invite.accepted', { inviteId, source: 'microfe-organization' });\n logger.info('mutation.success', {\n name: 'acceptInvite',\n inviteId: redactId(inviteId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('organization.invite.accept_failed', {\n inviteId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'acceptInvite',\n inviteId: redactId(inviteId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n\n/**\n * Hook to reject an organization invite\n */\nexport function useRejectInvite() {\n const { emit } = useOrganizationEventEmitter();\n const [rejectInvite, { loading, error }] = useRejectOrganizationInviteMutation({\n refetchQueries: [GetMyOrganizationInvitesDocument],\n });\n\n return {\n rejectInvite: async (inviteId: string) => {\n logger.info('mutation.start', {\n name: 'rejectInvite',\n inviteId: redactId(inviteId),\n });\n try {\n const result = await rejectInvite({ variables: { inviteId } });\n emit('organization.invite.rejected', { inviteId, source: 'microfe-organization' });\n logger.info('mutation.success', {\n name: 'rejectInvite',\n inviteId: redactId(inviteId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('organization.invite.reject_failed', {\n inviteId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'rejectInvite',\n inviteId: redactId(inviteId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n\n/**\n * Hook to cancel an organization invite\n */\nexport function useCancelInvite() {\n const { emit } = useOrganizationEventEmitter();\n const [cancelInvite, { loading, error }] = useCancelOrganizationInviteMutation({\n refetchQueries: [GetOrganizationInvitesDocument],\n });\n\n return {\n cancelInvite: async (inviteId: string) => {\n logger.info('mutation.start', {\n name: 'cancelInvite',\n inviteId: redactId(inviteId),\n });\n try {\n const result = await cancelInvite({ variables: { inviteId } });\n emit('organization.invite.cancelled', { inviteId, source: 'microfe-organization' });\n logger.info('mutation.success', {\n name: 'cancelInvite',\n inviteId: redactId(inviteId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('organization.invite.cancel_failed', {\n inviteId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'cancelInvite',\n inviteId: redactId(inviteId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n\n/**\n * Hook to resend an organization invite\n */\nexport function useResendInvite() {\n const { emit } = useOrganizationEventEmitter();\n const [resendInvite, { loading, error }] = useResendOrganizationInviteMutation({\n refetchQueries: [GetOrganizationInvitesDocument],\n });\n\n return {\n resendInvite: async (inviteId: string) => {\n logger.info('mutation.start', {\n name: 'resendInvite',\n inviteId: redactId(inviteId),\n });\n try {\n const result = await resendInvite({ variables: { inviteId } });\n emit('organization.invite.resent', { inviteId, source: 'microfe-organization' });\n logger.info('mutation.success', {\n name: 'resendInvite',\n inviteId: redactId(inviteId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('organization.invite.resend_failed', {\n inviteId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'resendInvite',\n inviteId: redactId(inviteId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n"],"mappings":";;;;;;;AAuBA,IAAM,IAA0C,CAAG;;;;;;;;;;;AAmCnD,SAAS,EAAiB,GAAoC;AAE5D,QADoB,GACA,gBAAgB,IAAI,YAAY;;AAGtD,SAAS,EAAoB,GAAwB;AAGnD,QAFI,aAAiB,QAAc,EAAM,UACrB,GACA,WAAW;;AAMjC,SAAgB,EACd,GACA,GACA,IAAgB,IAChB,IAAiB,GACjB;CACA,IAAM,EAAE,SAAM,YAAS,UAAO,eAAY,EAA+B;EACvE,WAAW;GAAE;GAAgB;GAAQ;GAAO;GAAQ;EACpD,MAAM,CAAC;EACP,aAAa;EACb,iBAAiB;EAClB,CAAC;AAEF,QAAO;EACL,SAAU,GAAM,qBAAqB,SAAS,EAAE;EAChD,OAAO,GAAM,qBAAqB,SAAS;EAC3C,SAAS,GAAM,qBAAqB,WAAW;EAC/C;EACA;EACA;EACD;;AAWH,SAAgB,EACd,GACA,IAAgB,IAChB,IAAiB,GACjB,IAAmB,IACnB;CACA,IAAM,EAAE,SAAM,YAAS,UAAO,eAAY,EAAiC;EACzE,WAAW;GAAE;GAAQ;GAAO;GAAQ;EACpC,MAAM,CAAC;EACP,aAAa;EACb,iBAAiB;EAClB,CAAC;AAEF,QAAO;EACL,SAAU,GAAM,uBAAuB,SAAS,EAAE;EAClD,OAAO,GAAM,uBAAuB,SAAS;EAC7C,SAAS,GAAM,uBAAuB,WAAW;EACjD;EACA;EACA;EACD;;AASH,SAAgB,EAAsB,GAAkB,IAAmB,IAAM;CAC/E,IAAM,EAAE,SAAM,YAAS,UAAO,eAAY,EAAgC;EACxE,WAAW,EAAE,IAAI,GAAU;EAC3B,MAAM,CAAC,KAAW,CAAC;EACnB,aAAa;EACb,iBAAiB;EAClB,CAAC;AAEF,QAAO;EACL,QAAS,GAAM,wBAAwB;EACvC;EACA;EACA;EACD;;AAMH,SAAgB,IAAkB;CAChC,IAAM,EAAE,YAAS,GAA6B,EACxC,CAAC,GAAc,EAAE,YAAS,cAAW,EAAoC,EAC7E,gBAAgB,CAAC,EAA+B,EACjD,CAAC;AAEF,QAAO;EACL,cAAc,OAAO,MAAuE;AAC1F,KAAO,KAAK,kBAAkB;IAC5B,MAAM;IACN,gBAAgB,EAAS,EAAM,eAAe;IAC/C,CAAC;AACF,OAAI;IACF,IAAM,IAAS,MAAM,EAAa,EAAE,WAAW,EAAE,UAAO,EAAE,CAAC,EACrD,IAAW,EAAO,MAAM,0BAA0B;AAWxD,WAVA,EAAK,+BAA+B;KAClC,gBAAgB,EAAM;KACtB;KACA,QAAQ;KACT,CAAC,EACF,EAAO,KAAK,oBAAoB;KAC9B,MAAM;KACN,gBAAgB,EAAS,EAAM,eAAe;KAC9C,UAAU,EAAS,EAAS;KAC7B,CAAC,EACK;YACA,GAAe;IACtB,IAAM,IAAY,EAAiB,EAAc,EAC3C,IAAe,EAAoB,EAAc;AAiBvD,UAhBA,EAAK,qCAAqC;KACxC,gBAAgB,EAAM;KACtB,QAAQ;KACR;KACA;KACD,CAAC,EACF,EAAO,MACL,mBACA;KACE,MAAM;KACN,gBAAgB,EAAS,EAAM,eAAe;KAC9C;KACA;KACD,EACD,EACD,EACK;;;EAGV;EACA;EACD;;AAMH,SAAgB,IAAkB;CAChC,IAAM,EAAE,YAAS,GAA6B,EACxC,CAAC,GAAc,EAAE,YAAS,cAAW,EAGzC,GAAyC,EACzC,gBAAgB,CAAC,GAAkC,EAAmB,EACvE,CAAC;AAEF,QAAO;EACL,cAAc,OAAO,MAAqB;AACxC,KAAO,KAAK,kBAAkB;IAC5B,MAAM;IACN,UAAU,EAAS,EAAS;IAC7B,CAAC;AACF,OAAI;IACF,IAAM,IAAiB,MAAM,EAAiB,gBAAgB,EACxD,IAAS,MAAM,EAAa,EAChC,WAAW;KAAE;KAAU,GAAI,IAAiB,EAAE,mBAAgB,GAAG,EAAE;KAAG,EACvE,CAAC;AAMF,WALA,EAAK,gCAAgC;KAAE;KAAU,QAAQ;KAAwB,CAAC,EAClF,EAAO,KAAK,oBAAoB;KAC9B,MAAM;KACN,UAAU,EAAS,EAAS;KAC7B,CAAC,EACK;YACA,GAAe;IACtB,IAAM,IAAY,EAAiB,EAAc,EAC3C,IAAe,EAAoB,EAAc;AAiBvD,UAhBA,EAAK,qCAAqC;KACxC;KACA,QAAQ;KACR;KACA;KACD,CAAC,EACF,EAAO,MACL,mBACA;KACE,MAAM;KACN,UAAU,EAAS,EAAS;KAC5B;KACA;KACD,EACD,EACD,EACK;;;EAGV;EACA;EACD;;AAMH,SAAgB,IAAkB;CAChC,IAAM,EAAE,YAAS,GAA6B,EACxC,CAAC,GAAc,EAAE,YAAS,cAAW,EAAoC,EAC7E,gBAAgB,CAAC,EAAiC,EACnD,CAAC;AAEF,QAAO;EACL,cAAc,OAAO,MAAqB;AACxC,KAAO,KAAK,kBAAkB;IAC5B,MAAM;IACN,UAAU,EAAS,EAAS;IAC7B,CAAC;AACF,OAAI;IACF,IAAM,IAAS,MAAM,EAAa,EAAE,WAAW,EAAE,aAAU,EAAE,CAAC;AAM9D,WALA,EAAK,gCAAgC;KAAE;KAAU,QAAQ;KAAwB,CAAC,EAClF,EAAO,KAAK,oBAAoB;KAC9B,MAAM;KACN,UAAU,EAAS,EAAS;KAC7B,CAAC,EACK;YACA,GAAe;IACtB,IAAM,IAAY,EAAiB,EAAc,EAC3C,IAAe,EAAoB,EAAc;AAiBvD,UAhBA,EAAK,qCAAqC;KACxC;KACA,QAAQ;KACR;KACA;KACD,CAAC,EACF,EAAO,MACL,mBACA;KACE,MAAM;KACN,UAAU,EAAS,EAAS;KAC5B;KACA;KACD,EACD,EACD,EACK;;;EAGV;EACA;EACD;;AAMH,SAAgB,IAAkB;CAChC,IAAM,EAAE,YAAS,GAA6B,EACxC,CAAC,GAAc,EAAE,YAAS,cAAW,EAAoC,EAC7E,gBAAgB,CAAC,EAA+B,EACjD,CAAC;AAEF,QAAO;EACL,cAAc,OAAO,MAAqB;AACxC,KAAO,KAAK,kBAAkB;IAC5B,MAAM;IACN,UAAU,EAAS,EAAS;IAC7B,CAAC;AACF,OAAI;IACF,IAAM,IAAS,MAAM,EAAa,EAAE,WAAW,EAAE,aAAU,EAAE,CAAC;AAM9D,WALA,EAAK,iCAAiC;KAAE;KAAU,QAAQ;KAAwB,CAAC,EACnF,EAAO,KAAK,oBAAoB;KAC9B,MAAM;KACN,UAAU,EAAS,EAAS;KAC7B,CAAC,EACK;YACA,GAAe;IACtB,IAAM,IAAY,EAAiB,EAAc,EAC3C,IAAe,EAAoB,EAAc;AAiBvD,UAhBA,EAAK,qCAAqC;KACxC;KACA,QAAQ;KACR;KACA;KACD,CAAC,EACF,EAAO,MACL,mBACA;KACE,MAAM;KACN,UAAU,EAAS,EAAS;KAC5B;KACA;KACD,EACD,EACD,EACK;;;EAGV;EACA;EACD;;AAMH,SAAgB,IAAkB;CAChC,IAAM,EAAE,YAAS,GAA6B,EACxC,CAAC,GAAc,EAAE,YAAS,cAAW,EAAoC,EAC7E,gBAAgB,CAAC,EAA+B,EACjD,CAAC;AAEF,QAAO;EACL,cAAc,OAAO,MAAqB;AACxC,KAAO,KAAK,kBAAkB;IAC5B,MAAM;IACN,UAAU,EAAS,EAAS;IAC7B,CAAC;AACF,OAAI;IACF,IAAM,IAAS,MAAM,EAAa,EAAE,WAAW,EAAE,aAAU,EAAE,CAAC;AAM9D,WALA,EAAK,8BAA8B;KAAE;KAAU,QAAQ;KAAwB,CAAC,EAChF,EAAO,KAAK,oBAAoB;KAC9B,MAAM;KACN,UAAU,EAAS,EAAS;KAC7B,CAAC,EACK;YACA,GAAe;IACtB,IAAM,IAAY,EAAiB,EAAc,EAC3C,IAAe,EAAoB,EAAc;AAiBvD,UAhBA,EAAK,qCAAqC;KACxC;KACA,QAAQ;KACR;KACA;KACD,CAAC,EACF,EAAO,MACL,mBACA;KACE,MAAM;KACN,UAAU,EAAS,EAAS;KAC5B;KACA;KACD,EACD,EACD,EACK;;;EAGV;EACA;EACD"}
1
+ {"version":3,"file":"useInvites.js","names":["apolloError","ACCEPT_ORGANIZATION_INVITE_WITH_CAPTCHA","extractErrorCode","error","extractErrorMessage","useOrganizationInvites","useGetOrganizationInvitesQuery","organizationId","data","useMyInvites","useGetMyOrganizationInvitesQuery","enabled","useOrganizationInvite","useGetMyOrganizationInviteQuery","inviteId","useInviteMember","useOrganizationEventEmitter","inviteMember","useInviteOrganizationMemberMutation","GetOrganizationInvitesDocument","redactId","input","result","emit","logger","mutationError","errorCode","errorMessage","useAcceptInvite","acceptInvite","useMutation","GetMyOrganizationInvitesDocument","GetMembersDocument","recaptchaToken","useRejectInvite","rejectInvite","useRejectOrganizationInviteMutation","useCancelInvite","cancelInvite","useCancelOrganizationInviteMutation","useResendInvite","resendInvite","useResendOrganizationInviteMutation"],"sources":["../../../../../src/organization-management/modules/members/hooks/useInvites.ts"],"sourcesContent":["import { gql } from '@apollo/client';\nimport { useMutation } from '@apollo/client/react';\nimport {\n useInviteOrganizationMemberMutation,\n useRejectOrganizationInviteMutation,\n useCancelOrganizationInviteMutation,\n useResendOrganizationInviteMutation,\n useGetOrganizationInvitesQuery,\n useGetMyOrganizationInvitesQuery,\n useGetMyOrganizationInviteQuery,\n GetOrganizationInvitesDocument,\n GetMyOrganizationInvitesDocument,\n GetMembersDocument,\n} from '../../../../generated/global-operations';\nimport type {\n InviteStatus,\n OrganizationInvite,\n OrganizationMember,\n} from '../../../../generated/global-types';\nimport { useOrganizationEventEmitter } from '../../../hooks/useOrganizationEventEmitter';\nimport { logger, redactId } from '../../../shared/logger';\nimport { executeRecaptcha } from '../../../shared/recaptcha';\n\nconst ACCEPT_ORGANIZATION_INVITE_WITH_CAPTCHA = gql`\n mutation AcceptOrganizationInviteWithCaptcha($inviteId: ID!, $recaptchaToken: String) {\n acceptOrganizationInvite(inviteId: $inviteId, recaptchaToken: $recaptchaToken) {\n id\n userId\n organizationId\n role\n joinedAt\n }\n }\n`;\n\ninterface AcceptOrganizationInviteData {\n acceptOrganizationInvite: OrganizationMember;\n}\n\ninterface AcceptOrganizationInviteVariables {\n inviteId: string;\n recaptchaToken?: string;\n}\n\ninterface GraphqlExtensions {\n code?: string;\n}\n\ninterface GraphqlError {\n message?: string;\n extensions?: GraphqlExtensions;\n}\n\ninterface ApolloLikeError {\n message?: string;\n graphQLErrors?: ReadonlyArray<GraphqlError>;\n}\n\nfunction extractErrorCode(error: unknown): string | undefined {\n const apolloError = error as ApolloLikeError | undefined;\n return apolloError?.graphQLErrors?.[0]?.extensions?.code;\n}\n\nfunction extractErrorMessage(error: unknown): string {\n if (error instanceof Error) return error.message;\n const apolloError = error as ApolloLikeError | undefined;\n return apolloError?.message ?? 'Unknown error';\n}\n\n/**\n * Hook to fetch organization invites (admin view)\n */\nexport function useOrganizationInvites(\n organizationId: string,\n filter?: { status?: InviteStatus },\n limit: number = 20,\n offset: number = 0\n) {\n const { data, loading, error, refetch } = useGetOrganizationInvitesQuery({\n variables: { organizationId, filter, limit, offset },\n skip: !organizationId,\n fetchPolicy: 'cache-first',\n nextFetchPolicy: 'cache-first',\n });\n\n return {\n invites: (data?.organizationInvites?.items ?? []) as OrganizationInvite[],\n total: data?.organizationInvites?.total ?? 0,\n hasMore: data?.organizationInvites?.hasMore ?? false,\n loading,\n error,\n refetch,\n };\n}\n\n/**\n * Hook to fetch invites for the current user (invitee view).\n *\n * `enabled` defaults to `true` for backward compat. Callers in admin /\n * service contexts (e.g. OrganizationsListPage in `mode=\"admin\"`) should\n * pass `false` to skip the network round-trip and avoid surfacing\n * authorization errors for actors that don't hold the self-scope.\n */\nexport function useMyInvites(\n status?: InviteStatus,\n limit: number = 20,\n offset: number = 0,\n enabled: boolean = true\n) {\n const { data, loading, error, refetch } = useGetMyOrganizationInvitesQuery({\n variables: { status, limit, offset },\n skip: !enabled,\n fetchPolicy: 'cache-first',\n nextFetchPolicy: 'cache-first',\n });\n\n return {\n invites: (data?.myOrganizationInvites?.items ?? []) as OrganizationInvite[],\n total: data?.myOrganizationInvites?.total ?? 0,\n hasMore: data?.myOrganizationInvites?.hasMore ?? false,\n loading,\n error,\n refetch,\n };\n}\n\n/**\n * Hook to fetch a SINGLE invite addressed to the current user, by id.\n * Backs the per-invite acceptance page reached from the invite email link.\n * `enabled` defaults to true; pass false to defer until the user is\n * authenticated (the query is self-scoped and 401s for anonymous callers).\n */\nexport function useOrganizationInvite(inviteId: string, enabled: boolean = true) {\n const { data, loading, error, refetch } = useGetMyOrganizationInviteQuery({\n variables: { id: inviteId },\n skip: !enabled || !inviteId,\n fetchPolicy: 'network-only',\n nextFetchPolicy: 'cache-first',\n });\n\n return {\n invite: (data?.myOrganizationInvite ?? null) as OrganizationInvite | null,\n loading,\n error,\n refetch,\n };\n}\n\n/**\n * Hook to invite a member by email\n */\nexport function useInviteMember() {\n const { emit } = useOrganizationEventEmitter();\n const [inviteMember, { loading, error }] = useInviteOrganizationMemberMutation({\n refetchQueries: [GetOrganizationInvitesDocument],\n });\n\n return {\n inviteMember: async (input: { organizationId: string; email: string; message?: string }) => {\n logger.info('mutation.start', {\n name: 'inviteMember',\n organizationId: redactId(input.organizationId),\n });\n try {\n const result = await inviteMember({ variables: { input } });\n const inviteId = result.data?.inviteOrganizationMember?.id;\n emit('organization.invite.created', {\n organizationId: input.organizationId,\n inviteId,\n source: 'microfe-organization',\n });\n logger.info('mutation.success', {\n name: 'inviteMember',\n organizationId: redactId(input.organizationId),\n inviteId: redactId(inviteId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('organization.invite.create_failed', {\n organizationId: input.organizationId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'inviteMember',\n organizationId: redactId(input.organizationId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n\n/**\n * Hook to accept an organization invite\n */\nexport function useAcceptInvite() {\n const { emit } = useOrganizationEventEmitter();\n const [acceptInvite, { loading, error }] = useMutation<\n AcceptOrganizationInviteData,\n AcceptOrganizationInviteVariables\n >(ACCEPT_ORGANIZATION_INVITE_WITH_CAPTCHA, {\n refetchQueries: [GetMyOrganizationInvitesDocument, GetMembersDocument],\n });\n\n return {\n acceptInvite: async (inviteId: string) => {\n logger.info('mutation.start', {\n name: 'acceptInvite',\n inviteId: redactId(inviteId),\n });\n try {\n const recaptchaToken = await executeRecaptcha('invite_accept');\n const result = await acceptInvite({\n variables: { inviteId, ...(recaptchaToken ? { recaptchaToken } : {}) },\n });\n emit('organization.invite.accepted', { inviteId, source: 'microfe-organization' });\n logger.info('mutation.success', {\n name: 'acceptInvite',\n inviteId: redactId(inviteId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('organization.invite.accept_failed', {\n inviteId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'acceptInvite',\n inviteId: redactId(inviteId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n\n/**\n * Hook to reject an organization invite\n */\nexport function useRejectInvite() {\n const { emit } = useOrganizationEventEmitter();\n const [rejectInvite, { loading, error }] = useRejectOrganizationInviteMutation({\n refetchQueries: [GetMyOrganizationInvitesDocument],\n });\n\n return {\n rejectInvite: async (inviteId: string) => {\n logger.info('mutation.start', {\n name: 'rejectInvite',\n inviteId: redactId(inviteId),\n });\n try {\n const result = await rejectInvite({ variables: { inviteId } });\n emit('organization.invite.rejected', { inviteId, source: 'microfe-organization' });\n logger.info('mutation.success', {\n name: 'rejectInvite',\n inviteId: redactId(inviteId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('organization.invite.reject_failed', {\n inviteId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'rejectInvite',\n inviteId: redactId(inviteId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n\n/**\n * Hook to cancel an organization invite\n */\nexport function useCancelInvite() {\n const { emit } = useOrganizationEventEmitter();\n const [cancelInvite, { loading, error }] = useCancelOrganizationInviteMutation({\n refetchQueries: [GetOrganizationInvitesDocument],\n });\n\n return {\n cancelInvite: async (inviteId: string) => {\n logger.info('mutation.start', {\n name: 'cancelInvite',\n inviteId: redactId(inviteId),\n });\n try {\n const result = await cancelInvite({ variables: { inviteId } });\n emit('organization.invite.cancelled', { inviteId, source: 'microfe-organization' });\n logger.info('mutation.success', {\n name: 'cancelInvite',\n inviteId: redactId(inviteId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('organization.invite.cancel_failed', {\n inviteId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'cancelInvite',\n inviteId: redactId(inviteId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n\n/**\n * Hook to resend an organization invite\n */\nexport function useResendInvite() {\n const { emit } = useOrganizationEventEmitter();\n const [resendInvite, { loading, error }] = useResendOrganizationInviteMutation({\n refetchQueries: [GetOrganizationInvitesDocument],\n });\n\n return {\n resendInvite: async (inviteId: string) => {\n logger.info('mutation.start', {\n name: 'resendInvite',\n inviteId: redactId(inviteId),\n });\n try {\n const result = await resendInvite({ variables: { inviteId } });\n emit('organization.invite.resent', { inviteId, source: 'microfe-organization' });\n logger.info('mutation.success', {\n name: 'resendInvite',\n inviteId: redactId(inviteId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('organization.invite.resend_failed', {\n inviteId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'resendInvite',\n inviteId: redactId(inviteId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { GetMembersDocument as e, useGetMemberQuery as t, useGetMembersQuery as n, useRemoveOrganizationMemberMutation as r } from "../../../../generated/global-operations.js";
2
2
  import { useOrganizationEventEmitter as i } from "../../../hooks/useOrganizationEventEmitter.js";
3
3
  import { logger as a, redactId as o } from "../../../shared/logger.js";
4
- //#region src/organization-management/modules/members/hooks/useMembers.ts
4
+ // src/organization-management/modules/members/hooks/useMembers.ts
5
5
  function s(e) {
6
6
  return e?.graphQLErrors?.[0]?.extensions?.code;
7
7
  }
@@ -89,7 +89,6 @@ function d() {
89
89
  error: u
90
90
  };
91
91
  }
92
- //#endregion
93
92
  export { u as useMember, l as useMembers, d as useRemoveMember };
94
93
 
95
94
  //# sourceMappingURL=useMembers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useMembers.js","names":[],"sources":["../../../../../src/organization-management/modules/members/hooks/useMembers.ts"],"sourcesContent":["import {\n useGetMembersQuery,\n useGetMemberQuery,\n useGetMembersByContextQuery,\n useGetMemberByEmailQuery,\n useAddOrganizationMemberMutation,\n useUpdateOrganizationMemberMutation,\n useRemoveOrganizationMemberMutation,\n GetMembersDocument,\n} from '../../../../generated/global-operations';\nimport type { Member, AddMemberInput, UpdateMemberInput } from '../types';\nimport { useOrganizationEventEmitter } from '../../../hooks/useOrganizationEventEmitter';\nimport { logger, redactId } from '../../../shared/logger';\n\ninterface GraphqlExtensions {\n code?: string;\n}\n\ninterface GraphqlError {\n message?: string;\n extensions?: GraphqlExtensions;\n}\n\ninterface ApolloLikeError {\n message?: string;\n graphQLErrors?: ReadonlyArray<GraphqlError>;\n}\n\nfunction extractErrorCode(error: unknown): string | undefined {\n const apolloError = error as ApolloLikeError | undefined;\n return apolloError?.graphQLErrors?.[0]?.extensions?.code;\n}\n\nfunction extractErrorMessage(error: unknown): string {\n if (error instanceof Error) return error.message;\n const apolloError = error as ApolloLikeError | undefined;\n return apolloError?.message ?? 'Unknown error';\n}\n\n/**\n * Hook to fetch organization members with pagination\n * Updated to use offset-based pagination (limit/offset) instead of cursor-based\n */\nexport function useMembers(\n organizationId: string,\n limit: number = 20,\n offset: number = 0,\n enabled: boolean = true\n) {\n const { data, loading, error, refetch, fetchMore } = useGetMembersQuery({\n variables: { organizationId, limit, offset },\n skip: !organizationId || !enabled,\n fetchPolicy: 'cache-first',\n nextFetchPolicy: 'cache-first',\n });\n\n return {\n members: (data?.organizationMembers?.items as Member[]) || [],\n total: data?.organizationMembers?.total || 0,\n limit: data?.organizationMembers?.limit || limit,\n offset: data?.organizationMembers?.offset || offset,\n hasMore: data?.organizationMembers?.hasMore || false,\n loading,\n error,\n refetch,\n fetchMore,\n };\n}\n\n/**\n * Hook to fetch a single member by filtering the members list\n * Note: Backend doesn't have single member query, we filter client-side\n */\nexport function useMember(organizationId: string, userId: string) {\n const { data, loading, error, refetch } = useGetMemberQuery({\n variables: { organizationId },\n skip: !organizationId || !userId,\n fetchPolicy: 'cache-first',\n nextFetchPolicy: 'cache-first',\n });\n\n // Find the member matching the userId from the list\n const member = data?.organizationMembers?.items?.find(\n (m: { userId: string }) => m.userId === userId\n ) as Member | undefined;\n\n return {\n member,\n loading,\n error,\n refetch,\n };\n}\n\n/**\n * Hook to fetch members by context (organization)\n * Uses the same query as useMembers but with different name for backward compatibility\n */\nexport function useMembersByContext(\n organizationId: string,\n limit: number = 20,\n offset: number = 0\n) {\n const { data, loading, error, refetch, fetchMore } = useGetMembersByContextQuery({\n variables: { organizationId, limit, offset },\n skip: !organizationId,\n fetchPolicy: 'cache-first',\n nextFetchPolicy: 'cache-first',\n });\n\n return {\n members: (data?.organizationMembers?.items as Member[]) || [],\n total: data?.organizationMembers?.total || 0,\n hasMore: data?.organizationMembers?.hasMore || false,\n loading,\n error,\n refetch,\n fetchMore,\n };\n}\n\n/**\n * Hook to fetch a member by email (client-side filtering)\n * Note: Backend doesn't have email-based query, we get all and filter\n */\nexport function useMemberByEmail(organizationId: string, email: string) {\n const { loading, error } = useGetMemberByEmailQuery({\n variables: { organizationId },\n skip: !organizationId || !email,\n fetchPolicy: 'cache-first',\n nextFetchPolicy: 'cache-first',\n });\n\n // Email is not currently exposed by the backend membership payload.\n // Return undefined instead of a misleading first item until a dedicated field/query exists.\n return {\n member: undefined as Member | undefined,\n loading,\n error,\n };\n}\n\n/**\n * Hook to add a new organization member\n */\nexport function useAddMember() {\n const { emit } = useOrganizationEventEmitter();\n const [addMember, { loading, error }] = useAddOrganizationMemberMutation({\n refetchQueries: [GetMembersDocument],\n });\n\n return {\n addMember: async (input: AddMemberInput) => {\n logger.info('mutation.start', {\n name: 'addMember',\n organizationId: redactId(input.organizationId),\n });\n try {\n const result = await addMember({ variables: { input } });\n emit('member.added', {\n organizationId: input.organizationId,\n memberId: input.userId,\n role: input.role ?? undefined,\n source: 'microfe-organization',\n });\n logger.info('mutation.success', {\n name: 'addMember',\n organizationId: redactId(input.organizationId),\n memberId: redactId(input.userId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('member.add_failed', {\n organizationId: input.organizationId,\n memberId: input.userId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'addMember',\n organizationId: redactId(input.organizationId),\n memberId: redactId(input.userId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n\n/**\n * Hook to update an organization member\n */\nexport function useUpdateMember() {\n const { emit } = useOrganizationEventEmitter();\n const [updateMember, { loading, error }] = useUpdateOrganizationMemberMutation();\n\n return {\n updateMember: async (organizationId: string, userId: string, input: UpdateMemberInput) => {\n logger.info('mutation.start', {\n name: 'updateMember',\n organizationId: redactId(organizationId),\n memberId: redactId(userId),\n });\n try {\n const result = await updateMember({ variables: { organizationId, userId, input } });\n emit('member.role_changed', {\n organizationId,\n memberId: userId,\n role: input.role ?? undefined,\n source: 'microfe-organization',\n });\n logger.info('mutation.success', {\n name: 'updateMember',\n organizationId: redactId(organizationId),\n memberId: redactId(userId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('member.role_change_failed', {\n organizationId,\n memberId: userId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'updateMember',\n organizationId: redactId(organizationId),\n memberId: redactId(userId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n\n/**\n * Hook to remove an organization member\n */\nexport function useRemoveMember() {\n const { emit } = useOrganizationEventEmitter();\n const [removeMember, { loading, error }] = useRemoveOrganizationMemberMutation({\n refetchQueries: [GetMembersDocument],\n });\n\n return {\n removeMember: async (organizationId: string, userId: string) => {\n logger.info('mutation.start', {\n name: 'removeMember',\n organizationId: redactId(organizationId),\n memberId: redactId(userId),\n });\n try {\n const result = await removeMember({ variables: { organizationId, userId } });\n emit('member.removed', {\n organizationId,\n memberId: userId,\n source: 'microfe-organization',\n });\n logger.info('mutation.success', {\n name: 'removeMember',\n organizationId: redactId(organizationId),\n memberId: redactId(userId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('member.remove_failed', {\n organizationId,\n memberId: userId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'removeMember',\n organizationId: redactId(organizationId),\n memberId: redactId(userId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n"],"mappings":";;;;AA4BA,SAAS,EAAiB,GAAoC;AAE5D,QADoB,GACA,gBAAgB,IAAI,YAAY;;AAGtD,SAAS,EAAoB,GAAwB;AAGnD,QAFI,aAAiB,QAAc,EAAM,UACrB,GACA,WAAW;;AAOjC,SAAgB,EACd,GACA,IAAgB,IAChB,IAAiB,GACjB,IAAmB,IACnB;CACA,IAAM,EAAE,SAAM,YAAS,UAAO,YAAS,iBAAc,EAAmB;EACtE,WAAW;GAAE;GAAgB;GAAO;GAAQ;EAC5C,MAAM,CAAC,KAAkB,CAAC;EAC1B,aAAa;EACb,iBAAiB;EAClB,CAAC;AAEF,QAAO;EACL,SAAU,GAAM,qBAAqB,SAAsB,EAAE;EAC7D,OAAO,GAAM,qBAAqB,SAAS;EAC3C,OAAO,GAAM,qBAAqB,SAAS;EAC3C,QAAQ,GAAM,qBAAqB,UAAU;EAC7C,SAAS,GAAM,qBAAqB,WAAW;EAC/C;EACA;EACA;EACA;EACD;;AAOH,SAAgB,EAAU,GAAwB,GAAgB;CAChE,IAAM,EAAE,SAAM,YAAS,UAAO,eAAY,EAAkB;EAC1D,WAAW,EAAE,mBAAgB;EAC7B,MAAM,CAAC,KAAkB,CAAC;EAC1B,aAAa;EACb,iBAAiB;EAClB,CAAC;AAOF,QAAO;EACL,QALa,GAAM,qBAAqB,OAAO,MAC9C,MAA0B,EAAE,WAAW,EACzC;EAIC;EACA;EACA;EACD;;AAyKH,SAAgB,IAAkB;CAChC,IAAM,EAAE,YAAS,GAA6B,EACxC,CAAC,GAAc,EAAE,YAAS,cAAW,EAAoC,EAC7E,gBAAgB,CAAC,EAAmB,EACrC,CAAC;AAEF,QAAO;EACL,cAAc,OAAO,GAAwB,MAAmB;AAC9D,KAAO,KAAK,kBAAkB;IAC5B,MAAM;IACN,gBAAgB,EAAS,EAAe;IACxC,UAAU,EAAS,EAAO;IAC3B,CAAC;AACF,OAAI;IACF,IAAM,IAAS,MAAM,EAAa,EAAE,WAAW;KAAE;KAAgB;KAAQ,EAAE,CAAC;AAW5E,WAVA,EAAK,kBAAkB;KACrB;KACA,UAAU;KACV,QAAQ;KACT,CAAC,EACF,EAAO,KAAK,oBAAoB;KAC9B,MAAM;KACN,gBAAgB,EAAS,EAAe;KACxC,UAAU,EAAS,EAAO;KAC3B,CAAC,EACK;YACA,GAAe;IACtB,IAAM,IAAY,EAAiB,EAAc,EAC3C,IAAe,EAAoB,EAAc;AAmBvD,UAlBA,EAAK,wBAAwB;KAC3B;KACA,UAAU;KACV,QAAQ;KACR;KACA;KACD,CAAC,EACF,EAAO,MACL,mBACA;KACE,MAAM;KACN,gBAAgB,EAAS,EAAe;KACxC,UAAU,EAAS,EAAO;KAC1B;KACA;KACD,EACD,EACD,EACK;;;EAGV;EACA;EACD"}
1
+ {"version":3,"file":"useMembers.js","names":["apolloError","extractErrorCode","error","extractErrorMessage","useMembers","useGetMembersQuery","organizationId","enabled","data","limit","offset","useMember","useGetMemberQuery","userId","m","useRemoveMember","useOrganizationEventEmitter","removeMember","useRemoveOrganizationMemberMutation","GetMembersDocument","redactId","result","emit","logger","mutationError","errorCode","errorMessage"],"sources":["../../../../../src/organization-management/modules/members/hooks/useMembers.ts"],"sourcesContent":["import {\n useGetMembersQuery,\n useGetMemberQuery,\n useGetMembersByContextQuery,\n useGetMemberByEmailQuery,\n useAddOrganizationMemberMutation,\n useUpdateOrganizationMemberMutation,\n useRemoveOrganizationMemberMutation,\n GetMembersDocument,\n} from '../../../../generated/global-operations';\nimport type { Member, AddMemberInput, UpdateMemberInput } from '../types';\nimport { useOrganizationEventEmitter } from '../../../hooks/useOrganizationEventEmitter';\nimport { logger, redactId } from '../../../shared/logger';\n\ninterface GraphqlExtensions {\n code?: string;\n}\n\ninterface GraphqlError {\n message?: string;\n extensions?: GraphqlExtensions;\n}\n\ninterface ApolloLikeError {\n message?: string;\n graphQLErrors?: ReadonlyArray<GraphqlError>;\n}\n\nfunction extractErrorCode(error: unknown): string | undefined {\n const apolloError = error as ApolloLikeError | undefined;\n return apolloError?.graphQLErrors?.[0]?.extensions?.code;\n}\n\nfunction extractErrorMessage(error: unknown): string {\n if (error instanceof Error) return error.message;\n const apolloError = error as ApolloLikeError | undefined;\n return apolloError?.message ?? 'Unknown error';\n}\n\n/**\n * Hook to fetch organization members with pagination\n * Updated to use offset-based pagination (limit/offset) instead of cursor-based\n */\nexport function useMembers(\n organizationId: string,\n limit: number = 20,\n offset: number = 0,\n enabled: boolean = true\n) {\n const { data, loading, error, refetch, fetchMore } = useGetMembersQuery({\n variables: { organizationId, limit, offset },\n skip: !organizationId || !enabled,\n fetchPolicy: 'cache-first',\n nextFetchPolicy: 'cache-first',\n });\n\n return {\n members: (data?.organizationMembers?.items as Member[]) || [],\n total: data?.organizationMembers?.total || 0,\n limit: data?.organizationMembers?.limit || limit,\n offset: data?.organizationMembers?.offset || offset,\n hasMore: data?.organizationMembers?.hasMore || false,\n loading,\n error,\n refetch,\n fetchMore,\n };\n}\n\n/**\n * Hook to fetch a single member by filtering the members list\n * Note: Backend doesn't have single member query, we filter client-side\n */\nexport function useMember(organizationId: string, userId: string) {\n const { data, loading, error, refetch } = useGetMemberQuery({\n variables: { organizationId },\n skip: !organizationId || !userId,\n fetchPolicy: 'cache-first',\n nextFetchPolicy: 'cache-first',\n });\n\n // Find the member matching the userId from the list\n const member = data?.organizationMembers?.items?.find(\n (m: { userId: string }) => m.userId === userId\n ) as Member | undefined;\n\n return {\n member,\n loading,\n error,\n refetch,\n };\n}\n\n/**\n * Hook to fetch members by context (organization)\n * Uses the same query as useMembers but with different name for backward compatibility\n */\nexport function useMembersByContext(\n organizationId: string,\n limit: number = 20,\n offset: number = 0\n) {\n const { data, loading, error, refetch, fetchMore } = useGetMembersByContextQuery({\n variables: { organizationId, limit, offset },\n skip: !organizationId,\n fetchPolicy: 'cache-first',\n nextFetchPolicy: 'cache-first',\n });\n\n return {\n members: (data?.organizationMembers?.items as Member[]) || [],\n total: data?.organizationMembers?.total || 0,\n hasMore: data?.organizationMembers?.hasMore || false,\n loading,\n error,\n refetch,\n fetchMore,\n };\n}\n\n/**\n * Hook to fetch a member by email (client-side filtering)\n * Note: Backend doesn't have email-based query, we get all and filter\n */\nexport function useMemberByEmail(organizationId: string, email: string) {\n const { loading, error } = useGetMemberByEmailQuery({\n variables: { organizationId },\n skip: !organizationId || !email,\n fetchPolicy: 'cache-first',\n nextFetchPolicy: 'cache-first',\n });\n\n // Email is not currently exposed by the backend membership payload.\n // Return undefined instead of a misleading first item until a dedicated field/query exists.\n return {\n member: undefined as Member | undefined,\n loading,\n error,\n };\n}\n\n/**\n * Hook to add a new organization member\n */\nexport function useAddMember() {\n const { emit } = useOrganizationEventEmitter();\n const [addMember, { loading, error }] = useAddOrganizationMemberMutation({\n refetchQueries: [GetMembersDocument],\n });\n\n return {\n addMember: async (input: AddMemberInput) => {\n logger.info('mutation.start', {\n name: 'addMember',\n organizationId: redactId(input.organizationId),\n });\n try {\n const result = await addMember({ variables: { input } });\n emit('member.added', {\n organizationId: input.organizationId,\n memberId: input.userId,\n role: input.role ?? undefined,\n source: 'microfe-organization',\n });\n logger.info('mutation.success', {\n name: 'addMember',\n organizationId: redactId(input.organizationId),\n memberId: redactId(input.userId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('member.add_failed', {\n organizationId: input.organizationId,\n memberId: input.userId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'addMember',\n organizationId: redactId(input.organizationId),\n memberId: redactId(input.userId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n\n/**\n * Hook to update an organization member\n */\nexport function useUpdateMember() {\n const { emit } = useOrganizationEventEmitter();\n const [updateMember, { loading, error }] = useUpdateOrganizationMemberMutation();\n\n return {\n updateMember: async (organizationId: string, userId: string, input: UpdateMemberInput) => {\n logger.info('mutation.start', {\n name: 'updateMember',\n organizationId: redactId(organizationId),\n memberId: redactId(userId),\n });\n try {\n const result = await updateMember({ variables: { organizationId, userId, input } });\n emit('member.role_changed', {\n organizationId,\n memberId: userId,\n role: input.role ?? undefined,\n source: 'microfe-organization',\n });\n logger.info('mutation.success', {\n name: 'updateMember',\n organizationId: redactId(organizationId),\n memberId: redactId(userId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('member.role_change_failed', {\n organizationId,\n memberId: userId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'updateMember',\n organizationId: redactId(organizationId),\n memberId: redactId(userId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n\n/**\n * Hook to remove an organization member\n */\nexport function useRemoveMember() {\n const { emit } = useOrganizationEventEmitter();\n const [removeMember, { loading, error }] = useRemoveOrganizationMemberMutation({\n refetchQueries: [GetMembersDocument],\n });\n\n return {\n removeMember: async (organizationId: string, userId: string) => {\n logger.info('mutation.start', {\n name: 'removeMember',\n organizationId: redactId(organizationId),\n memberId: redactId(userId),\n });\n try {\n const result = await removeMember({ variables: { organizationId, userId } });\n emit('member.removed', {\n organizationId,\n memberId: userId,\n source: 'microfe-organization',\n });\n logger.info('mutation.success', {\n name: 'removeMember',\n organizationId: redactId(organizationId),\n memberId: redactId(userId),\n });\n return result;\n } catch (mutationError) {\n const errorCode = extractErrorCode(mutationError);\n const errorMessage = extractErrorMessage(mutationError);\n emit('member.remove_failed', {\n organizationId,\n memberId: userId,\n source: 'microfe-organization',\n errorCode,\n errorMessage,\n });\n logger.error(\n 'mutation.failed',\n {\n name: 'removeMember',\n organizationId: redactId(organizationId),\n memberId: redactId(userId),\n errorCode,\n errorMessage,\n },\n mutationError\n );\n throw mutationError;\n }\n },\n loading,\n error,\n };\n}\n"],"mappings":";;;;AA4BA,SAASC,EAAiB,GAAoC;CAE5D,OAAOD,GAAa,gBAAgB,EAAE,EAAE,YAAY;AACtD;AAEA,SAASG,EAAoB,GAAwB;CAGnD,OAFID,aAAiB,QAAcA,EAAM,UAElCF,GAAa,WAAW;AACjC;AAMA,SAAgBI,EACd,GACA,IAAgB,IAChB,IAAiB,GACjB,IAAmB,IACnB;CACA,IAAM,EAAE,SAAM,YAAS,UAAO,YAAS,iBAAcC,EAAmB;EACtE,WAAW;GAAE;GAAgB;GAAO;EAAO;EAC3C,MAAM,CAACC,KAAkB,CAACC;EAC1B,aAAa;EACb,iBAAiB;CACnB,CAAC;CAED,OAAO;EACL,SAAUC,GAAM,qBAAqB,SAAsB,CAAC;EAC5D,OAAOA,GAAM,qBAAqB,SAAS;EAC3C,OAAOA,GAAM,qBAAqB,SAASC;EAC3C,QAAQD,GAAM,qBAAqB,UAAUE;EAC7C,SAASF,GAAM,qBAAqB,WAAW;EAC/C;EACA;EACA;EACA;CACF;AACF;AAMA,SAAgBG,EAAU,GAAwB,GAAgB;CAChE,IAAM,EAAE,SAAM,YAAS,UAAO,eAAYC,EAAkB;EAC1D,WAAW,EAAE,kBAAe;EAC5B,MAAM,CAACN,KAAkB,CAACO;EAC1B,aAAa;EACb,iBAAiB;CACnB,CAAC;CAOD,OAAO;EACL,QALaL,GAAM,qBAAqB,OAAO,MAC9C,MAA0BM,EAAE,WAAWD,CAC1C;EAIE;EACA;EACA;CACF;AACF;AAwKA,SAAgBE,IAAkB;CAChC,IAAM,EAAE,YAASC,EAA4B,GACvC,CAACC,GAAc,EAAE,YAAS,cAAWC,EAAoC,EAC7E,gBAAgB,CAACC,CAAkB,EACrC,CAAC;CAED,OAAO;EACL,cAAc,OAAO,GAAwB,MAAmB;GAC9D,EAAO,KAAK,kBAAkB;IAC5B,MAAM;IACN,gBAAgBC,EAASd,CAAc;IACvC,UAAUc,EAASP,CAAM;GAC3B,CAAC;GACD,IAAI;IACF,IAAMQ,IAAS,MAAMJ,EAAa,EAAE,WAAW;KAAE;KAAgB;IAAO,EAAE,CAAC;IAW3E,OAVAK,EAAK,kBAAkB;KACrB;KACA,UAAUT;KACV,QAAQ;IACV,CAAC,GACDU,EAAO,KAAK,oBAAoB;KAC9B,MAAM;KACN,gBAAgBH,EAASd,CAAc;KACvC,UAAUc,EAASP,CAAM;IAC3B,CAAC,GACMQ;GACT,SAASG,GAAe;IACtB,IAAMC,IAAYxB,EAAiBuB,CAAa,GAC1CE,IAAevB,EAAoBqB,CAAa;IAmBtD,MAlBAF,EAAK,wBAAwB;KAC3B;KACA,UAAUT;KACV,QAAQ;KACR;KACA;IACF,CAAC,GACDU,EAAO,MACL,mBACA;KACE,MAAM;KACN,gBAAgBH,EAASd,CAAc;KACvC,UAAUc,EAASP,CAAM;KACzB;KACA;IACF,GACAW,CACF,GACMA;GACR;EACF;EACA;EACA;CACF;AACF"}
@@ -1,7 +1,7 @@
1
1
  import { useOrgConsole as e } from "../../../providers/OrgConsoleProvider.js";
2
2
  import { useCallback as t, useEffect as n, useMemo as r, useRef as i, useState as a } from "react";
3
3
  import { graphqlFetch as o } from "@burdenoff/fe-libs/shared/graphql";
4
- //#region src/organization-management/modules/members/hooks/useWorkspaceInvites.ts
4
+ // src/organization-management/modules/members/hooks/useWorkspaceInvites.ts
5
5
  var s = "\n query GetMyPendingWorkspaceInvites {\n myPendingInvitations {\n id\n email\n status\n roleIds\n workspaceId\n invitedById\n expiresAt\n createdAt\n projectId\n invitedUserId\n updatedAt\n deletedAt\n context {\n type\n metadata\n }\n }\n }\n", c = "\n mutation AcceptWorkspaceInvite($id: ID!) {\n acceptInvitation(id: $id) {\n id\n status\n workspaceId\n updatedAt\n }\n }\n", l = "\n mutation RejectWorkspaceInvite($id: ID!) {\n rejectInvitation(id: $id) {\n id\n status\n workspaceId\n updatedAt\n }\n }\n";
6
6
  function u(e, t) {
7
7
  return e instanceof Error ? e : Error(t);
@@ -112,7 +112,6 @@ function m() {
112
112
  error: s
113
113
  };
114
114
  }
115
- //#endregion
116
115
  export { p as useAcceptWorkspaceInvite, f as useMyWorkspaceInvites, m as useRejectWorkspaceInvite };
117
116
 
118
117
  //# sourceMappingURL=useWorkspaceInvites.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useWorkspaceInvites.js","names":[],"sources":["../../../../../src/organization-management/modules/members/hooks/useWorkspaceInvites.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport type { Invitation } from '../../../../generated/wspace-types';\nimport { useOrgConsole } from '../../../providers/OrgConsoleProvider';\n\nconst GET_MY_PENDING_WORKSPACE_INVITES = `\n query GetMyPendingWorkspaceInvites {\n myPendingInvitations {\n id\n email\n status\n roleIds\n workspaceId\n invitedById\n expiresAt\n createdAt\n projectId\n invitedUserId\n updatedAt\n deletedAt\n context {\n type\n metadata\n }\n }\n }\n`;\n\nconst ACCEPT_WORKSPACE_INVITE = `\n mutation AcceptWorkspaceInvite($id: ID!) {\n acceptInvitation(id: $id) {\n id\n status\n workspaceId\n updatedAt\n }\n }\n`;\n\nconst REJECT_WORKSPACE_INVITE = `\n mutation RejectWorkspaceInvite($id: ID!) {\n rejectInvitation(id: $id) {\n id\n status\n workspaceId\n updatedAt\n }\n }\n`;\n\ninterface WorkspaceInvitesResponse {\n myPendingInvitations: Invitation[];\n}\n\ninterface WorkspaceInviteMutationResponse {\n acceptInvitation?: Pick<Invitation, 'id' | 'status' | 'workspaceId' | 'updatedAt'>;\n rejectInvitation?: Pick<Invitation, 'id' | 'status' | 'workspaceId' | 'updatedAt'>;\n}\n\nfunction toError(error: unknown, fallback: string) {\n return error instanceof Error ? error : new Error(fallback);\n}\n\nfunction isAbortLikeError(error: unknown) {\n if (!(error instanceof Error)) {\n return false;\n }\n\n return error.name === 'AbortError' || error.message.toLowerCase().includes('signal is aborted');\n}\n\nexport function useMyWorkspaceInvites(email?: string, enabled: boolean = true) {\n const { authToken } = useOrgConsole();\n const shouldFetch = enabled && Boolean(email);\n const [invites, setInvites] = useState<Invitation[]>([]);\n const [loading, setLoading] = useState(shouldFetch);\n const [error, setError] = useState<Error | null>(null);\n const requestIdRef = useRef(0);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const loadInvites = useCallback(\n async (signal?: AbortSignal) => {\n if (!enabled || !email) {\n setInvites([]);\n setError(null);\n setLoading(false);\n return [] as Invitation[];\n }\n\n const requestId = ++requestIdRef.current;\n setLoading(true);\n setError(null);\n\n try {\n const result = await graphqlFetch<WorkspaceInvitesResponse>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: GET_MY_PENDING_WORKSPACE_INVITES,\n signal,\n workspaceToken: false,\n });\n\n if (result.errors?.length) {\n if (signal?.aborted) {\n return [] as Invitation[];\n }\n\n throw new Error(result.errors[0]?.message || 'Failed to fetch workspace invites');\n }\n\n const nextInvites = result.data?.myPendingInvitations ?? [];\n if (requestIdRef.current === requestId) {\n setInvites(nextInvites);\n }\n return nextInvites;\n } catch (fetchError) {\n if (signal?.aborted || isAbortLikeError(fetchError)) {\n return [] as Invitation[];\n }\n\n const normalizedError = toError(fetchError, 'Failed to fetch workspace invites');\n if (requestIdRef.current === requestId) {\n setError(normalizedError);\n setInvites([]);\n }\n throw normalizedError;\n } finally {\n if (requestIdRef.current === requestId) {\n setLoading(false);\n }\n }\n },\n [authToken, email, enabled]\n );\n\n useEffect(() => {\n const abortController = new AbortController();\n abortControllerRef.current?.abort();\n abortControllerRef.current = abortController;\n\n void loadInvites(abortController.signal).catch(() => undefined);\n\n return () => {\n if (abortControllerRef.current === abortController) {\n abortControllerRef.current = null;\n }\n abortController.abort();\n };\n }, [loadInvites]);\n\n const isLoading =\n loading ||\n (shouldFetch && invites.length === 0 && error === null && requestIdRef.current === 0);\n\n return useMemo(\n () => ({\n invites,\n total: invites.length,\n loading: isLoading,\n error,\n refetch: loadInvites,\n }),\n [error, invites, isLoading, loadInvites]\n );\n}\n\nexport function useAcceptWorkspaceInvite() {\n const { authToken } = useOrgConsole();\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const acceptInvite = useCallback(\n async (inviteId: string) => {\n setLoading(true);\n setError(null);\n\n try {\n const result = await graphqlFetch<WorkspaceInviteMutationResponse>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: ACCEPT_WORKSPACE_INVITE,\n variables: { id: inviteId },\n workspaceToken: false,\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'Failed to accept workspace invite');\n }\n\n return result.data?.acceptInvitation ?? null;\n } catch (mutationError) {\n const normalizedError = toError(mutationError, 'Failed to accept workspace invite');\n setError(normalizedError);\n throw normalizedError;\n } finally {\n setLoading(false);\n }\n },\n [authToken]\n );\n\n return { acceptInvite, loading, error };\n}\n\nexport function useRejectWorkspaceInvite() {\n const { authToken } = useOrgConsole();\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const rejectInvite = useCallback(\n async (inviteId: string) => {\n setLoading(true);\n setError(null);\n\n try {\n const result = await graphqlFetch<WorkspaceInviteMutationResponse>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: REJECT_WORKSPACE_INVITE,\n variables: { id: inviteId },\n workspaceToken: false,\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'Failed to reject workspace invite');\n }\n\n return result.data?.rejectInvitation ?? null;\n } catch (mutationError) {\n const normalizedError = toError(mutationError, 'Failed to reject workspace invite');\n setError(normalizedError);\n throw normalizedError;\n } finally {\n setLoading(false);\n }\n },\n [authToken]\n );\n\n return { rejectInvite, loading, error };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useWorkspaceInvites.js","names":["GET_MY_PENDING_WORKSPACE_INVITES","ACCEPT_WORKSPACE_INVITE","REJECT_WORKSPACE_INVITE","toError","error","fallback","isAbortLikeError","useMyWorkspaceInvites","useOrgConsole","shouldFetch","enabled","email","invites","setInvites","useState","loading","setLoading","setError","requestIdRef","useRef","abortControllerRef","loadInvites","useCallback","requestId","result","graphqlFetch","authToken","signal","nextInvites","fetchError","normalizedError","abortController","isLoading","useMemo","useAcceptWorkspaceInvite","inviteId","mutationError","useRejectWorkspaceInvite"],"sources":["../../../../../src/organization-management/modules/members/hooks/useWorkspaceInvites.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport type { Invitation } from '../../../../generated/wspace-types';\nimport { useOrgConsole } from '../../../providers/OrgConsoleProvider';\n\nconst GET_MY_PENDING_WORKSPACE_INVITES = `\n query GetMyPendingWorkspaceInvites {\n myPendingInvitations {\n id\n email\n status\n roleIds\n workspaceId\n invitedById\n expiresAt\n createdAt\n projectId\n invitedUserId\n updatedAt\n deletedAt\n context {\n type\n metadata\n }\n }\n }\n`;\n\nconst ACCEPT_WORKSPACE_INVITE = `\n mutation AcceptWorkspaceInvite($id: ID!) {\n acceptInvitation(id: $id) {\n id\n status\n workspaceId\n updatedAt\n }\n }\n`;\n\nconst REJECT_WORKSPACE_INVITE = `\n mutation RejectWorkspaceInvite($id: ID!) {\n rejectInvitation(id: $id) {\n id\n status\n workspaceId\n updatedAt\n }\n }\n`;\n\ninterface WorkspaceInvitesResponse {\n myPendingInvitations: Invitation[];\n}\n\ninterface WorkspaceInviteMutationResponse {\n acceptInvitation?: Pick<Invitation, 'id' | 'status' | 'workspaceId' | 'updatedAt'>;\n rejectInvitation?: Pick<Invitation, 'id' | 'status' | 'workspaceId' | 'updatedAt'>;\n}\n\nfunction toError(error: unknown, fallback: string) {\n return error instanceof Error ? error : new Error(fallback);\n}\n\nfunction isAbortLikeError(error: unknown) {\n if (!(error instanceof Error)) {\n return false;\n }\n\n return error.name === 'AbortError' || error.message.toLowerCase().includes('signal is aborted');\n}\n\nexport function useMyWorkspaceInvites(email?: string, enabled: boolean = true) {\n const { authToken } = useOrgConsole();\n const shouldFetch = enabled && Boolean(email);\n const [invites, setInvites] = useState<Invitation[]>([]);\n const [loading, setLoading] = useState(shouldFetch);\n const [error, setError] = useState<Error | null>(null);\n const requestIdRef = useRef(0);\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const loadInvites = useCallback(\n async (signal?: AbortSignal) => {\n if (!enabled || !email) {\n setInvites([]);\n setError(null);\n setLoading(false);\n return [] as Invitation[];\n }\n\n const requestId = ++requestIdRef.current;\n setLoading(true);\n setError(null);\n\n try {\n const result = await graphqlFetch<WorkspaceInvitesResponse>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: GET_MY_PENDING_WORKSPACE_INVITES,\n signal,\n workspaceToken: false,\n });\n\n if (result.errors?.length) {\n if (signal?.aborted) {\n return [] as Invitation[];\n }\n\n throw new Error(result.errors[0]?.message || 'Failed to fetch workspace invites');\n }\n\n const nextInvites = result.data?.myPendingInvitations ?? [];\n if (requestIdRef.current === requestId) {\n setInvites(nextInvites);\n }\n return nextInvites;\n } catch (fetchError) {\n if (signal?.aborted || isAbortLikeError(fetchError)) {\n return [] as Invitation[];\n }\n\n const normalizedError = toError(fetchError, 'Failed to fetch workspace invites');\n if (requestIdRef.current === requestId) {\n setError(normalizedError);\n setInvites([]);\n }\n throw normalizedError;\n } finally {\n if (requestIdRef.current === requestId) {\n setLoading(false);\n }\n }\n },\n [authToken, email, enabled]\n );\n\n useEffect(() => {\n const abortController = new AbortController();\n abortControllerRef.current?.abort();\n abortControllerRef.current = abortController;\n\n void loadInvites(abortController.signal).catch(() => undefined);\n\n return () => {\n if (abortControllerRef.current === abortController) {\n abortControllerRef.current = null;\n }\n abortController.abort();\n };\n }, [loadInvites]);\n\n const isLoading =\n loading ||\n (shouldFetch && invites.length === 0 && error === null && requestIdRef.current === 0);\n\n return useMemo(\n () => ({\n invites,\n total: invites.length,\n loading: isLoading,\n error,\n refetch: loadInvites,\n }),\n [error, invites, isLoading, loadInvites]\n );\n}\n\nexport function useAcceptWorkspaceInvite() {\n const { authToken } = useOrgConsole();\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const acceptInvite = useCallback(\n async (inviteId: string) => {\n setLoading(true);\n setError(null);\n\n try {\n const result = await graphqlFetch<WorkspaceInviteMutationResponse>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: ACCEPT_WORKSPACE_INVITE,\n variables: { id: inviteId },\n workspaceToken: false,\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'Failed to accept workspace invite');\n }\n\n return result.data?.acceptInvitation ?? null;\n } catch (mutationError) {\n const normalizedError = toError(mutationError, 'Failed to accept workspace invite');\n setError(normalizedError);\n throw normalizedError;\n } finally {\n setLoading(false);\n }\n },\n [authToken]\n );\n\n return { acceptInvite, loading, error };\n}\n\nexport function useRejectWorkspaceInvite() {\n const { authToken } = useOrgConsole();\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const rejectInvite = useCallback(\n async (inviteId: string) => {\n setLoading(true);\n setError(null);\n\n try {\n const result = await graphqlFetch<WorkspaceInviteMutationResponse>({\n gateway: 'workspace',\n authToken: authToken || undefined,\n query: REJECT_WORKSPACE_INVITE,\n variables: { id: inviteId },\n workspaceToken: false,\n });\n\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message || 'Failed to reject workspace invite');\n }\n\n return result.data?.rejectInvitation ?? null;\n } catch (mutationError) {\n const normalizedError = toError(mutationError, 'Failed to reject workspace invite');\n setError(normalizedError);\n throw normalizedError;\n } finally {\n setLoading(false);\n }\n },\n [authToken]\n );\n\n return { rejectInvite, loading, error };\n}\n"],"mappings":"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"}