@burdenoff/microfe-organization 2026.625.2 → 2026.626.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 (37) hide show
  1. package/dist/organization-management/modules/members/components/InviteStatusBadge.js +6 -2
  2. package/dist/organization-management/modules/members/components/InviteStatusBadge.js.map +1 -1
  3. package/dist/organization-management/modules/members/pages/InviteMemberPage.js +58 -53
  4. package/dist/organization-management/modules/members/pages/InviteMemberPage.js.map +1 -1
  5. package/dist/organization-management/modules/members/pages/InvitePeoplePage.js +56 -52
  6. package/dist/organization-management/modules/members/pages/InvitePeoplePage.js.map +1 -1
  7. package/dist/organization-management/modules/members/pages/MemberDetailPage.js +72 -68
  8. package/dist/organization-management/modules/members/pages/MemberDetailPage.js.map +1 -1
  9. package/dist/organization-management/modules/members/pages/MembersListPage.js +232 -225
  10. package/dist/organization-management/modules/members/pages/MembersListPage.js.map +1 -1
  11. package/dist/organization-management/modules/members/pages/MyInvitesPage.js +172 -182
  12. package/dist/organization-management/modules/members/pages/MyInvitesPage.js.map +1 -1
  13. package/dist/organization-management/modules/members/pages/OrganizationInviteAcceptancePage.js +132 -128
  14. package/dist/organization-management/modules/members/pages/OrganizationInviteAcceptancePage.js.map +1 -1
  15. package/dist/organization-management/modules/organizations/components/OrganizationStatusBadge.js +5 -1
  16. package/dist/organization-management/modules/organizations/components/OrganizationStatusBadge.js.map +1 -1
  17. package/dist/organization-management/modules/organizations/pages/OrganizationCreatePage.js +42 -37
  18. package/dist/organization-management/modules/organizations/pages/OrganizationCreatePage.js.map +1 -1
  19. package/dist/organization-management/modules/organizations/pages/OrganizationDetailPage.js +316 -266
  20. package/dist/organization-management/modules/organizations/pages/OrganizationDetailPage.js.map +1 -1
  21. package/dist/organization-management/modules/organizations/pages/OrganizationEditPage.js +52 -47
  22. package/dist/organization-management/modules/organizations/pages/OrganizationEditPage.js.map +1 -1
  23. package/dist/organization-management/modules/organizations/pages/OrganizationsListPage.js +108 -96
  24. package/dist/organization-management/modules/organizations/pages/OrganizationsListPage.js.map +1 -1
  25. package/dist/organization-management/modules/workspaces/components/WorkspaceStatusBadge.js +5 -1
  26. package/dist/organization-management/modules/workspaces/components/WorkspaceStatusBadge.js.map +1 -1
  27. package/dist/organization-management/modules/workspaces/pages/WorkspaceCreatePage.js +43 -38
  28. package/dist/organization-management/modules/workspaces/pages/WorkspaceCreatePage.js.map +1 -1
  29. package/dist/organization-management/modules/workspaces/pages/WorkspaceDetailPage.js +341 -286
  30. package/dist/organization-management/modules/workspaces/pages/WorkspaceDetailPage.js.map +1 -1
  31. package/dist/organization-management/modules/workspaces/pages/WorkspaceEditPage.js +50 -45
  32. package/dist/organization-management/modules/workspaces/pages/WorkspaceEditPage.js.map +1 -1
  33. package/dist/organization-management/modules/workspaces/pages/WorkspacesListPage.js +219 -209
  34. package/dist/organization-management/modules/workspaces/pages/WorkspacesListPage.js.map +1 -1
  35. package/package.json +2 -2
  36. package/dist/organization-management/shared/components/feedback/EmptyState.js +0 -31
  37. package/dist/organization-management/shared/components/feedback/EmptyState.js.map +0 -1
@@ -8,7 +8,8 @@ var l = {
8
8
  labelKey: "members.inviteStatus.pending",
9
9
  defaultLabel: "Pending",
10
10
  className: "bg-[var(--color-status-warning-bgSubtle)] text-[var(--color-status-warning-text)] border border-[var(--color-status-warning-border)]",
11
- icon: i
11
+ icon: i,
12
+ pulse: !0
12
13
  },
13
14
  ACCEPTED: {
14
15
  labelKey: "members.inviteStatus.accepted",
@@ -42,7 +43,10 @@ function u({ status: t }) {
42
43
  }, [n]), i = l[t] ?? l.PENDING, a = i.icon;
43
44
  return /* @__PURE__ */ s("span", {
44
45
  className: `inline-flex items-center gap-1 px-2.5 py-0.5 rounded-full text-xs font-medium ${i.className}`,
45
- children: [/* @__PURE__ */ o(a, { size: 12 }), r(i.labelKey, i.defaultLabel)]
46
+ children: [/* @__PURE__ */ o(a, {
47
+ size: 12,
48
+ className: i.pulse ? "motion-safe:animate-vc-glow-pulse" : ""
49
+ }), r(i.labelKey, i.defaultLabel)]
46
50
  });
47
51
  }
48
52
  //#endregion
@@ -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 }\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 },\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} />\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;EACP;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,EAAM,MAAM,IAAM,CAAA,EACjB,EAAG,EAAO,UAAU,EAAO,aAAa,CACpC"}
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"}
@@ -9,114 +9,119 @@ import { BulkInviteForm as s } from "../components/BulkInviteForm.js";
9
9
  import { PendingInvitesList as c } from "../components/PendingInvitesList.js";
10
10
  import { useState as l } from "react";
11
11
  import { ArrowLeft as u, UserPlus as d } from "lucide-react";
12
- import { GlassCard as f, ShowMore as p } from "@burdenoff/fe-libs/ui";
13
- import { usePermissions as m } from "@burdenoff/fe-libs/shared/providers/shell";
14
- import { jsx as h, jsxs as g } from "react/jsx-runtime";
15
- import { useParams as _ } from "react-router-dom";
12
+ import { GlassCard as f, PagePurpose as p, ShowMore as m } from "@burdenoff/fe-libs/ui";
13
+ import { usePermissions as h } from "@burdenoff/fe-libs/shared/providers/shell";
14
+ import { jsx as g, jsxs as _ } from "react/jsx-runtime";
15
+ import { useParams as v } from "react-router-dom";
16
16
  //#region src/organization-management/modules/members/pages/InviteMemberPage.tsx
17
- function v() {
18
- let v = r(), { organizationId: y } = _(), { navigate: b, basePath: x = "/organizations" } = e(), { hasPermission: S, isLoading: C } = m(), { inviteMember: w, loading: T, error: E } = n(), [D, O] = l("single"), k = async (e) => {
19
- await w(e), t.success(`${v("members.invite.success", "Invitation sent to")} ${e.email}`);
20
- }, A = () => {
21
- b(`${x}/${y}/members`);
17
+ function y() {
18
+ let y = r(), { organizationId: b } = v(), { navigate: x, basePath: S = "/organizations" } = e(), { hasPermission: C, isLoading: w } = h(), { inviteMember: T, loading: E, error: D } = n(), [O, k] = l("single"), A = async (e) => {
19
+ await T(e), t.success(`${y("members.invite.success", "Invitation sent to")} ${e.email}`);
20
+ }, j = () => {
21
+ x(`${S}/${b}/members`);
22
22
  };
23
- return C ? /* @__PURE__ */ h("div", {
23
+ return w ? /* @__PURE__ */ g("div", {
24
24
  className: "min-h-full bg-[var(--color-bg-canvas)] p-6",
25
- children: /* @__PURE__ */ h(i, { message: v("common.loadingPermissions", "Loading permissions...") })
26
- }) : S(a.MEMBER_INVITE) ? /* @__PURE__ */ h("div", {
25
+ children: /* @__PURE__ */ g(i, { message: y("common.loadingPermissions", "Loading permissions...") })
26
+ }) : C(a.MEMBER_INVITE) ? /* @__PURE__ */ g("div", {
27
27
  className: "min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6",
28
- children: /* @__PURE__ */ g("div", {
28
+ children: /* @__PURE__ */ _("div", {
29
29
  className: "mx-auto max-w-3xl space-y-8",
30
30
  children: [
31
- /* @__PURE__ */ g("div", {
31
+ /* @__PURE__ */ _("div", {
32
32
  className: "flex items-center gap-3",
33
- children: [/* @__PURE__ */ h("button", {
33
+ children: [/* @__PURE__ */ g("button", {
34
34
  type: "button",
35
- onClick: A,
35
+ onClick: j,
36
36
  className: "rounded-lg p-2 transition-colors hover:bg-[var(--color-bg-subtle)]",
37
- "aria-label": v("members.invite.backToMembers", "Back to members"),
38
- children: /* @__PURE__ */ h(u, {
37
+ "aria-label": y("members.invite.backToMembers", "Back to members"),
38
+ children: /* @__PURE__ */ g(u, {
39
39
  size: 20,
40
40
  className: "text-[var(--color-text-secondary)]"
41
41
  })
42
- }), /* @__PURE__ */ g("div", {
42
+ }), /* @__PURE__ */ _("div", {
43
43
  className: "flex items-center gap-2",
44
- children: [/* @__PURE__ */ h(d, {
44
+ children: [/* @__PURE__ */ g(d, {
45
45
  size: 24,
46
46
  className: "text-[var(--color-text-primary)]"
47
- }), /* @__PURE__ */ h("h1", {
47
+ }), /* @__PURE__ */ g("h1", {
48
48
  className: "text-2xl font-bold text-[var(--color-text-primary)]",
49
- children: v("members.invite.title", "Invite Member")
49
+ children: y("members.invite.title", "Invite Member")
50
50
  })]
51
51
  })]
52
52
  }),
53
- /* @__PURE__ */ h("div", {
53
+ /* @__PURE__ */ g(p, {
54
+ className: "max-w-2xl",
55
+ children: y("members.invite.purpose", "Send someone an invitation to join this organization. Invite one person by email, or upload a CSV to invite a whole team at once — invitees accept from their own account and instantly gain access to the organization.")
56
+ }),
57
+ /* @__PURE__ */ g("div", {
54
58
  className: "inline-flex rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] p-1",
55
59
  role: "tablist",
56
- "aria-label": v("members.invite.modeToggle", "Invite mode"),
60
+ "aria-label": y("members.invite.modeToggle", "Invite mode"),
57
61
  children: ["single", "bulk"].map((e) => {
58
- let t = D === e, n = e === "single" ? v("members.invite.modeSingle", "Single") : v("members.invite.modeBulk", "Bulk (CSV)");
59
- return /* @__PURE__ */ h("button", {
62
+ let t = O === e, n = e === "single" ? y("members.invite.modeSingle", "Single") : y("members.invite.modeBulk", "Bulk (CSV)");
63
+ return /* @__PURE__ */ g("button", {
60
64
  type: "button",
61
65
  role: "tab",
62
66
  "aria-selected": t,
63
- onClick: () => O(e),
67
+ onClick: () => k(e),
64
68
  className: `min-h-9 rounded-md px-4 py-1.5 text-sm font-medium transition-colors ${t ? "bg-[var(--color-action-primary-bg)] text-[var(--color-action-primary-text)]" : "text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)]"}`,
65
69
  children: n
66
70
  }, e);
67
71
  })
68
72
  }),
69
- /* @__PURE__ */ g(f, {
70
- treatment: "plain",
73
+ /* @__PURE__ */ _(f, {
74
+ treatment: "glass",
75
+ glow: !0,
71
76
  className: "border-border-seam p-6",
72
77
  children: [
73
- /* @__PURE__ */ h("h2", {
78
+ /* @__PURE__ */ g("h2", {
74
79
  className: "text-lg font-semibold text-[var(--color-text-primary)] mb-4",
75
- children: D === "single" ? v("members.invite.send", "Send Invite") : v("members.bulkInvite.title", "Bulk Invite from CSV")
80
+ children: O === "single" ? y("members.invite.send", "Send Invite") : y("members.bulkInvite.title", "Bulk Invite from CSV")
76
81
  }),
77
- /* @__PURE__ */ h("p", {
82
+ /* @__PURE__ */ g("p", {
78
83
  className: "text-sm text-[var(--color-text-muted)] mb-6",
79
- children: D === "single" ? v("members.invite.description", "Enter the email address of the person you want to invite. They will receive an email notification and can accept or decline from their account.") : v("members.bulkInvite.pageDescription", "Upload a CSV to invite many people at once. Download the template below to see the expected format.")
84
+ children: O === "single" ? y("members.invite.description", "Enter the email address of the person you want to invite. They will receive an email notification and can accept or decline from their account.") : y("members.bulkInvite.pageDescription", "Upload a CSV to invite many people at once. Download the template below to see the expected format.")
80
85
  }),
81
- D === "single" && E && /* @__PURE__ */ h("div", {
86
+ O === "single" && D && /* @__PURE__ */ g("div", {
82
87
  className: "mb-4 rounded-lg border border-[var(--color-status-error-border)] bg-[var(--color-status-error-bgSubtle)] p-3",
83
- children: /* @__PURE__ */ h("p", {
88
+ children: /* @__PURE__ */ g("p", {
84
89
  className: "text-sm text-[var(--color-status-error-text)]",
85
- children: E.message.includes("CONFLICT") ? v("members.invite.error.conflict", "An invite already exists for this email address.") : E.message.includes("already a member") ? v("members.invite.error.alreadyMember", "This user is already a member of the organization.") : E.message
90
+ children: D.message.includes("CONFLICT") ? y("members.invite.error.conflict", "An invite already exists for this email address.") : D.message.includes("already a member") ? y("members.invite.error.alreadyMember", "This user is already a member of the organization.") : D.message
86
91
  })
87
92
  }),
88
- D === "single" ? /* @__PURE__ */ h(o, {
89
- organizationId: y,
90
- onSubmit: k,
91
- onCancel: A,
92
- loading: T
93
- }) : /* @__PURE__ */ h(s, {
94
- organizationId: y,
95
- inviteMember: w,
96
- onCancel: A,
97
- loading: T
93
+ O === "single" ? /* @__PURE__ */ g(o, {
94
+ organizationId: b,
95
+ onSubmit: A,
96
+ onCancel: j,
97
+ loading: E
98
+ }) : /* @__PURE__ */ g(s, {
99
+ organizationId: b,
100
+ inviteMember: T,
101
+ onCancel: j,
102
+ loading: E
98
103
  })
99
104
  ]
100
105
  }),
101
- /* @__PURE__ */ h(f, {
106
+ /* @__PURE__ */ g(f, {
102
107
  treatment: "plain",
103
108
  className: "border-border-seam p-6",
104
- children: /* @__PURE__ */ h(p, {
109
+ children: /* @__PURE__ */ g(m, {
105
110
  collapsedHeight: 260,
106
- children: /* @__PURE__ */ h(c, { organizationId: y })
111
+ children: /* @__PURE__ */ g(c, { organizationId: b })
107
112
  })
108
113
  })
109
114
  ]
110
115
  })
111
- }) : /* @__PURE__ */ h("div", {
116
+ }) : /* @__PURE__ */ g("div", {
112
117
  className: "min-h-full bg-[var(--color-bg-canvas)] p-6",
113
- children: /* @__PURE__ */ h("div", {
118
+ children: /* @__PURE__ */ g("div", {
114
119
  className: "p-8 text-center text-[var(--color-text-secondary)]",
115
- children: v("members.invite.noPermission", "You don't have permission to invite members.")
120
+ children: y("members.invite.noPermission", "You don't have permission to invite members.")
116
121
  })
117
122
  });
118
123
  }
119
124
  //#endregion
120
- export { v as InviteMemberPage };
125
+ export { y as InviteMemberPage };
121
126
 
122
127
  //# sourceMappingURL=InviteMemberPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"InviteMemberPage.js","names":[],"sources":["../../../../../src/organization-management/modules/members/pages/InviteMemberPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { ArrowLeft, UserPlus } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { GlassCard, ShowMore } from '@burdenoff/fe-libs/ui';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useOrgConsole } from '../../../providers/OrgConsoleProvider';\nimport { useInviteMember } from '../hooks/useInvites';\nimport { InviteMemberForm } from '../components/InviteMemberForm';\nimport { BulkInviteForm } from '../components/BulkInviteForm';\nimport { PendingInvitesList } from '../components/PendingInvitesList';\nimport { LoadingState } from '../../../shared/components/feedback/LoadingState';\nimport { PERMISSIONS } from '../../../constants/permissions';\nimport { useTr } from '../../../shared/hooks/useTr';\n\ntype InviteMode = 'single' | 'bulk';\n\n/**\n * Invite Member Page\n * Email-based invite form with pending invites list below\n */\nexport function InviteMemberPage() {\n const tr = useTr();\n const { organizationId } = useParams<{ organizationId: string }>();\n const { navigate, basePath = '/organizations' } = useOrgConsole();\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n const { inviteMember, loading, error } = useInviteMember();\n const [mode, setMode] = useState<InviteMode>('single');\n\n const handleSubmit = async (data: {\n organizationId: string;\n email: string;\n message?: string;\n }) => {\n await inviteMember(data);\n toast.success(`${tr('members.invite.success', 'Invitation sent to')} ${data.email}`);\n };\n\n const handleCancel = () => {\n navigate(`${basePath}/${organizationId}/members`);\n };\n\n if (permissionsLoading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <LoadingState message={tr('common.loadingPermissions', 'Loading permissions...')} />\n </div>\n );\n }\n\n if (!hasPermission(PERMISSIONS.MEMBER_INVITE)) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <div className=\"p-8 text-center text-[var(--color-text-secondary)]\">\n {tr('members.invite.noPermission', \"You don't have permission to invite members.\")}\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <div className=\"mx-auto max-w-3xl space-y-8\">\n {/* Header */}\n <div className=\"flex items-center gap-3\">\n <button\n type=\"button\"\n onClick={handleCancel}\n className=\"rounded-lg p-2 transition-colors hover:bg-[var(--color-bg-subtle)]\"\n aria-label={tr('members.invite.backToMembers', 'Back to members')}\n >\n <ArrowLeft size={20} className=\"text-[var(--color-text-secondary)]\" />\n </button>\n <div className=\"flex items-center gap-2\">\n <UserPlus size={24} className=\"text-[var(--color-text-primary)]\" />\n <h1 className=\"text-2xl font-bold text-[var(--color-text-primary)]\">\n {tr('members.invite.title', 'Invite Member')}\n </h1>\n </div>\n </div>\n\n {/* Mode toggle */}\n <div\n className=\"inline-flex rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] p-1\"\n role=\"tablist\"\n aria-label={tr('members.invite.modeToggle', 'Invite mode')}\n >\n {(['single', 'bulk'] as const).map((m) => {\n const isActive = mode === m;\n const label =\n m === 'single'\n ? tr('members.invite.modeSingle', 'Single')\n : tr('members.invite.modeBulk', 'Bulk (CSV)');\n return (\n <button\n key={m}\n type=\"button\"\n role=\"tab\"\n aria-selected={isActive}\n onClick={() => setMode(m)}\n className={`min-h-9 rounded-md px-4 py-1.5 text-sm font-medium transition-colors ${\n isActive\n ? 'bg-[var(--color-action-primary-bg)] text-[var(--color-action-primary-text)]'\n : 'text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)]'\n }`}\n >\n {label}\n </button>\n );\n })}\n </div>\n\n {/* Invite Form Card */}\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-6\">\n <h2 className=\"text-lg font-semibold text-[var(--color-text-primary)] mb-4\">\n {mode === 'single'\n ? tr('members.invite.send', 'Send Invite')\n : tr('members.bulkInvite.title', 'Bulk Invite from CSV')}\n </h2>\n <p className=\"text-sm text-[var(--color-text-muted)] mb-6\">\n {mode === 'single'\n ? tr(\n 'members.invite.description',\n 'Enter the email address of the person you want to invite. They will receive an email notification and can accept or decline from their account.'\n )\n : tr(\n 'members.bulkInvite.pageDescription',\n 'Upload a CSV to invite many people at once. Download the template below to see the expected format.'\n )}\n </p>\n\n {mode === 'single' && error && (\n <div className=\"mb-4 rounded-lg border border-[var(--color-status-error-border)] bg-[var(--color-status-error-bgSubtle)] p-3\">\n <p className=\"text-sm text-[var(--color-status-error-text)]\">\n {error.message.includes('CONFLICT')\n ? tr(\n 'members.invite.error.conflict',\n 'An invite already exists for this email address.'\n )\n : error.message.includes('already a member')\n ? tr(\n 'members.invite.error.alreadyMember',\n 'This user is already a member of the organization.'\n )\n : error.message}\n </p>\n </div>\n )}\n\n {mode === 'single' ? (\n <InviteMemberForm\n organizationId={organizationId!}\n onSubmit={handleSubmit}\n onCancel={handleCancel}\n loading={loading}\n />\n ) : (\n <BulkInviteForm\n organizationId={organizationId!}\n inviteMember={inviteMember}\n onCancel={handleCancel}\n loading={loading}\n />\n )}\n </GlassCard>\n\n {/* Pending Invites */}\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-6\">\n <ShowMore collapsedHeight={260}>\n <PendingInvitesList organizationId={organizationId!} />\n </ShowMore>\n </GlassCard>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAqBA,SAAgB,IAAmB;CACjC,IAAM,IAAK,GAAO,EACZ,EAAE,sBAAmB,GAAuC,EAC5D,EAAE,aAAU,cAAW,qBAAqB,GAAe,EAC3D,EAAE,kBAAe,WAAW,MAAuB,GAAgB,EACnE,EAAE,iBAAc,YAAS,aAAU,GAAiB,EACpD,CAAC,GAAM,KAAW,EAAqB,SAAS,EAEhD,IAAe,OAAO,MAItB;AAEJ,EADA,MAAM,EAAa,EAAK,EACxB,EAAM,QAAQ,GAAG,EAAG,0BAA0B,qBAAqB,CAAC,GAAG,EAAK,QAAQ;IAGhF,UAAqB;AACzB,IAAS,GAAG,EAAS,GAAG,EAAe,UAAU;;AAqBnD,QAlBI,IAEA,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD,EAAc,SAAS,EAAG,6BAA6B,yBAAyB,EAAI,CAAA;EAChF,CAAA,GAIL,EAAc,EAAY,cAAc,GAW3C,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD;GAAK,WAAU;aAAf;IAEE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,UAAD;MACE,MAAK;MACL,SAAS;MACT,WAAU;MACV,cAAY,EAAG,gCAAgC,kBAAkB;gBAEjE,kBAAC,GAAD;OAAW,MAAM;OAAI,WAAU;OAAuC,CAAA;MAC/D,CAAA,EACT,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD;OAAU,MAAM;OAAI,WAAU;OAAqC,CAAA,EACnE,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAG,wBAAwB,gBAAgB;OACzC,CAAA,CACD;QACF;;IAGN,kBAAC,OAAD;KACE,WAAU;KACV,MAAK;KACL,cAAY,EAAG,6BAA6B,cAAc;eAExD,CAAC,UAAU,OAAO,CAAW,KAAK,MAAM;MACxC,IAAM,IAAW,MAAS,GACpB,IACJ,MAAM,WACF,EAAG,6BAA6B,SAAS,GACzC,EAAG,2BAA2B,aAAa;AACjD,aACE,kBAAC,UAAD;OAEE,MAAK;OACL,MAAK;OACL,iBAAe;OACf,eAAe,EAAQ,EAAE;OACzB,WAAW,wEACT,IACI,gFACA;iBAGL;OACM,EAZF,EAYE;OAEX;KACE,CAAA;IAGN,kBAAC,GAAD;KAAW,WAAU;KAAQ,WAAU;eAAvC;MACE,kBAAC,MAAD;OAAI,WAAU;iBACX,MAAS,WACN,EAAG,uBAAuB,cAAc,GACxC,EAAG,4BAA4B,uBAAuB;OACvD,CAAA;MACL,kBAAC,KAAD;OAAG,WAAU;iBACV,MAAS,WACN,EACE,8BACA,kJACD,GACD,EACE,sCACA,sGACD;OACH,CAAA;MAEH,MAAS,YAAY,KACpB,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAM,QAAQ,SAAS,WAAW,GAC/B,EACE,iCACA,mDACD,GACD,EAAM,QAAQ,SAAS,mBAAmB,GACxC,EACE,sCACA,qDACD,GACD,EAAM;QACV,CAAA;OACA,CAAA;MAGP,MAAS,WACR,kBAAC,GAAD;OACkB;OAChB,UAAU;OACV,UAAU;OACD;OACT,CAAA,GAEF,kBAAC,GAAD;OACkB;OACF;OACd,UAAU;OACD;OACT,CAAA;MAEM;;IAGZ,kBAAC,GAAD;KAAW,WAAU;KAAQ,WAAU;eACrC,kBAAC,GAAD;MAAU,iBAAiB;gBACzB,kBAAC,GAAD,EAAoC,mBAAmB,CAAA;MAC9C,CAAA;KACD,CAAA;IACR;;EACF,CAAA,GAzHJ,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAG,+BAA+B,+CAA+C;GAC9E,CAAA;EACF,CAAA"}
1
+ {"version":3,"file":"InviteMemberPage.js","names":[],"sources":["../../../../../src/organization-management/modules/members/pages/InviteMemberPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { ArrowLeft, UserPlus } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { GlassCard, PagePurpose, ShowMore } from '@burdenoff/fe-libs/ui';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useOrgConsole } from '../../../providers/OrgConsoleProvider';\nimport { useInviteMember } from '../hooks/useInvites';\nimport { InviteMemberForm } from '../components/InviteMemberForm';\nimport { BulkInviteForm } from '../components/BulkInviteForm';\nimport { PendingInvitesList } from '../components/PendingInvitesList';\nimport { LoadingState } from '../../../shared/components/feedback/LoadingState';\nimport { PERMISSIONS } from '../../../constants/permissions';\nimport { useTr } from '../../../shared/hooks/useTr';\n\ntype InviteMode = 'single' | 'bulk';\n\n/**\n * Invite Member Page\n * Email-based invite form with pending invites list below\n */\nexport function InviteMemberPage() {\n const tr = useTr();\n const { organizationId } = useParams<{ organizationId: string }>();\n const { navigate, basePath = '/organizations' } = useOrgConsole();\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n const { inviteMember, loading, error } = useInviteMember();\n const [mode, setMode] = useState<InviteMode>('single');\n\n const handleSubmit = async (data: {\n organizationId: string;\n email: string;\n message?: string;\n }) => {\n await inviteMember(data);\n toast.success(`${tr('members.invite.success', 'Invitation sent to')} ${data.email}`);\n };\n\n const handleCancel = () => {\n navigate(`${basePath}/${organizationId}/members`);\n };\n\n if (permissionsLoading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <LoadingState message={tr('common.loadingPermissions', 'Loading permissions...')} />\n </div>\n );\n }\n\n if (!hasPermission(PERMISSIONS.MEMBER_INVITE)) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <div className=\"p-8 text-center text-[var(--color-text-secondary)]\">\n {tr('members.invite.noPermission', \"You don't have permission to invite members.\")}\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <div className=\"mx-auto max-w-3xl space-y-8\">\n {/* Header */}\n <div className=\"flex items-center gap-3\">\n <button\n type=\"button\"\n onClick={handleCancel}\n className=\"rounded-lg p-2 transition-colors hover:bg-[var(--color-bg-subtle)]\"\n aria-label={tr('members.invite.backToMembers', 'Back to members')}\n >\n <ArrowLeft size={20} className=\"text-[var(--color-text-secondary)]\" />\n </button>\n <div className=\"flex items-center gap-2\">\n <UserPlus size={24} className=\"text-[var(--color-text-primary)]\" />\n <h1 className=\"text-2xl font-bold text-[var(--color-text-primary)]\">\n {tr('members.invite.title', 'Invite Member')}\n </h1>\n </div>\n </div>\n\n <PagePurpose className=\"max-w-2xl\">\n {tr(\n 'members.invite.purpose',\n 'Send someone an invitation to join this organization. Invite one person by email, or upload a CSV to invite a whole team at once — invitees accept from their own account and instantly gain access to the organization.'\n )}\n </PagePurpose>\n\n {/* Mode toggle */}\n <div\n className=\"inline-flex rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] p-1\"\n role=\"tablist\"\n aria-label={tr('members.invite.modeToggle', 'Invite mode')}\n >\n {(['single', 'bulk'] as const).map((m) => {\n const isActive = mode === m;\n const label =\n m === 'single'\n ? tr('members.invite.modeSingle', 'Single')\n : tr('members.invite.modeBulk', 'Bulk (CSV)');\n return (\n <button\n key={m}\n type=\"button\"\n role=\"tab\"\n aria-selected={isActive}\n onClick={() => setMode(m)}\n className={`min-h-9 rounded-md px-4 py-1.5 text-sm font-medium transition-colors ${\n isActive\n ? 'bg-[var(--color-action-primary-bg)] text-[var(--color-action-primary-text)]'\n : 'text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)]'\n }`}\n >\n {label}\n </button>\n );\n })}\n </div>\n\n {/* Invite Form Card */}\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam p-6\">\n <h2 className=\"text-lg font-semibold text-[var(--color-text-primary)] mb-4\">\n {mode === 'single'\n ? tr('members.invite.send', 'Send Invite')\n : tr('members.bulkInvite.title', 'Bulk Invite from CSV')}\n </h2>\n <p className=\"text-sm text-[var(--color-text-muted)] mb-6\">\n {mode === 'single'\n ? tr(\n 'members.invite.description',\n 'Enter the email address of the person you want to invite. They will receive an email notification and can accept or decline from their account.'\n )\n : tr(\n 'members.bulkInvite.pageDescription',\n 'Upload a CSV to invite many people at once. Download the template below to see the expected format.'\n )}\n </p>\n\n {mode === 'single' && error && (\n <div className=\"mb-4 rounded-lg border border-[var(--color-status-error-border)] bg-[var(--color-status-error-bgSubtle)] p-3\">\n <p className=\"text-sm text-[var(--color-status-error-text)]\">\n {error.message.includes('CONFLICT')\n ? tr(\n 'members.invite.error.conflict',\n 'An invite already exists for this email address.'\n )\n : error.message.includes('already a member')\n ? tr(\n 'members.invite.error.alreadyMember',\n 'This user is already a member of the organization.'\n )\n : error.message}\n </p>\n </div>\n )}\n\n {mode === 'single' ? (\n <InviteMemberForm\n organizationId={organizationId!}\n onSubmit={handleSubmit}\n onCancel={handleCancel}\n loading={loading}\n />\n ) : (\n <BulkInviteForm\n organizationId={organizationId!}\n inviteMember={inviteMember}\n onCancel={handleCancel}\n loading={loading}\n />\n )}\n </GlassCard>\n\n {/* Pending Invites */}\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-6\">\n <ShowMore collapsedHeight={260}>\n <PendingInvitesList organizationId={organizationId!} />\n </ShowMore>\n </GlassCard>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAqBA,SAAgB,IAAmB;CACjC,IAAM,IAAK,GAAO,EACZ,EAAE,sBAAmB,GAAuC,EAC5D,EAAE,aAAU,cAAW,qBAAqB,GAAe,EAC3D,EAAE,kBAAe,WAAW,MAAuB,GAAgB,EACnE,EAAE,iBAAc,YAAS,aAAU,GAAiB,EACpD,CAAC,GAAM,KAAW,EAAqB,SAAS,EAEhD,IAAe,OAAO,MAItB;AAEJ,EADA,MAAM,EAAa,EAAK,EACxB,EAAM,QAAQ,GAAG,EAAG,0BAA0B,qBAAqB,CAAC,GAAG,EAAK,QAAQ;IAGhF,UAAqB;AACzB,IAAS,GAAG,EAAS,GAAG,EAAe,UAAU;;AAqBnD,QAlBI,IAEA,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD,EAAc,SAAS,EAAG,6BAA6B,yBAAyB,EAAI,CAAA;EAChF,CAAA,GAIL,EAAc,EAAY,cAAc,GAW3C,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD;GAAK,WAAU;aAAf;IAEE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,UAAD;MACE,MAAK;MACL,SAAS;MACT,WAAU;MACV,cAAY,EAAG,gCAAgC,kBAAkB;gBAEjE,kBAAC,GAAD;OAAW,MAAM;OAAI,WAAU;OAAuC,CAAA;MAC/D,CAAA,EACT,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD;OAAU,MAAM;OAAI,WAAU;OAAqC,CAAA,EACnE,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAG,wBAAwB,gBAAgB;OACzC,CAAA,CACD;QACF;;IAEN,kBAAC,GAAD;KAAa,WAAU;eACpB,EACC,0BACA,2NACD;KACW,CAAA;IAGd,kBAAC,OAAD;KACE,WAAU;KACV,MAAK;KACL,cAAY,EAAG,6BAA6B,cAAc;eAExD,CAAC,UAAU,OAAO,CAAW,KAAK,MAAM;MACxC,IAAM,IAAW,MAAS,GACpB,IACJ,MAAM,WACF,EAAG,6BAA6B,SAAS,GACzC,EAAG,2BAA2B,aAAa;AACjD,aACE,kBAAC,UAAD;OAEE,MAAK;OACL,MAAK;OACL,iBAAe;OACf,eAAe,EAAQ,EAAE;OACzB,WAAW,wEACT,IACI,gFACA;iBAGL;OACM,EAZF,EAYE;OAEX;KACE,CAAA;IAGN,kBAAC,GAAD;KAAW,WAAU;KAAQ,MAAA;KAAK,WAAU;eAA5C;MACE,kBAAC,MAAD;OAAI,WAAU;iBACX,MAAS,WACN,EAAG,uBAAuB,cAAc,GACxC,EAAG,4BAA4B,uBAAuB;OACvD,CAAA;MACL,kBAAC,KAAD;OAAG,WAAU;iBACV,MAAS,WACN,EACE,8BACA,kJACD,GACD,EACE,sCACA,sGACD;OACH,CAAA;MAEH,MAAS,YAAY,KACpB,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAM,QAAQ,SAAS,WAAW,GAC/B,EACE,iCACA,mDACD,GACD,EAAM,QAAQ,SAAS,mBAAmB,GACxC,EACE,sCACA,qDACD,GACD,EAAM;QACV,CAAA;OACA,CAAA;MAGP,MAAS,WACR,kBAAC,GAAD;OACkB;OAChB,UAAU;OACV,UAAU;OACD;OACT,CAAA,GAEF,kBAAC,GAAD;OACkB;OACF;OACd,UAAU;OACD;OACT,CAAA;MAEM;;IAGZ,kBAAC,GAAD;KAAW,WAAU;KAAQ,WAAU;eACrC,kBAAC,GAAD;MAAU,iBAAiB;gBACzB,kBAAC,GAAD,EAAoC,mBAAmB,CAAA;MAC9C,CAAA;KACD,CAAA;IACR;;EACF,CAAA,GAhIJ,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAG,+BAA+B,+CAA+C;GAC9E,CAAA;EACF,CAAA"}
@@ -3,85 +3,89 @@ import { useMyOrganizations as t } from "../../organizations/hooks/useOrganizati
3
3
  import { useTr as n } from "../../../shared/hooks/useTr.js";
4
4
  import { LoadingState as r } from "../../../shared/components/feedback/LoadingState.js";
5
5
  import { ErrorState as i } from "../../../shared/components/feedback/ErrorState.js";
6
- import { EmptyState as a } from "../../../shared/components/feedback/EmptyState.js";
7
- import { useOrganizationPageView as o } from "../../../hooks/useOrganizationPageView.js";
8
- import { useOrgsWithPermission as s } from "../../organizations/hooks/useOrgsWithPermission.js";
9
- import { useEffect as c, useMemo as l, useState as u } from "react";
10
- import { Building as d, ChevronRight as f, UserPlus as p } from "lucide-react";
11
- import { GlassCard as m } from "@burdenoff/fe-libs/ui";
12
- import { jsx as h, jsxs as g } from "react/jsx-runtime";
6
+ import { useOrganizationPageView as a } from "../../../hooks/useOrganizationPageView.js";
7
+ import { useOrgsWithPermission as o } from "../../organizations/hooks/useOrgsWithPermission.js";
8
+ import { useEffect as s, useMemo as c, useState as l } from "react";
9
+ import { Building as u, ChevronRight as d, UserPlus as f } from "lucide-react";
10
+ import { GlassCard as p, IllustratedEmptyState as m, PagePurpose as h } from "@burdenoff/fe-libs/ui";
11
+ import { jsx as g, jsxs as _ } from "react/jsx-runtime";
13
12
  //#region src/organization-management/modules/members/pages/InvitePeoplePage.tsx
14
- function _() {
15
- o("organizations.invite-people");
16
- let _ = n(), { navigate: v, basePath: y = "/organizations" } = e(), { organizations: b, loading: x, error: S } = t(100, 0), { allowedIds: C, loading: w, isError: T } = s(l(() => b.map((e) => e.id), [b]), "member", "create"), E = l(() => b.filter((e) => C.has(e.id)), [b, C]), [D, O] = u(!1);
17
- return c(() => {
18
- D || x || w || E.length === 1 && (O(!0), v(`${y}/${E[0].id}/members/invite`));
13
+ function v() {
14
+ a("organizations.invite-people");
15
+ let v = n(), { navigate: y, basePath: b = "/organizations" } = e(), { organizations: x, loading: S, error: C } = t(100, 0), { allowedIds: w, loading: T, isError: E } = o(c(() => x.map((e) => e.id), [x]), "member", "create"), D = c(() => x.filter((e) => w.has(e.id)), [x, w]), [O, k] = l(!1);
16
+ return s(() => {
17
+ O || S || T || D.length === 1 && (k(!0), y(`${b}/${D[0].id}/members/invite`));
19
18
  }, [
19
+ O,
20
+ S,
21
+ T,
20
22
  D,
21
- x,
22
- w,
23
- E,
24
- v,
25
- y
26
- ]), x || w ? /* @__PURE__ */ h("div", {
23
+ y,
24
+ b
25
+ ]), S || T ? /* @__PURE__ */ g("div", {
27
26
  className: "min-h-full bg-[var(--color-bg-canvas)] p-6",
28
- children: /* @__PURE__ */ h(r, { message: _("common.loading", "Loading...") })
29
- }) : S || T ? /* @__PURE__ */ h("div", {
27
+ children: /* @__PURE__ */ g(r, { message: v("common.loading", "Loading...") })
28
+ }) : C || E ? /* @__PURE__ */ g("div", {
30
29
  className: "min-h-full bg-[var(--color-bg-canvas)] p-6",
31
- children: /* @__PURE__ */ h(i, { message: S?.message || _("members.invitePeople.error", "Failed to load organizations for invite.") })
32
- }) : /* @__PURE__ */ h("div", {
30
+ children: /* @__PURE__ */ g(i, { message: C?.message || v("members.invitePeople.error", "Failed to load organizations for invite.") })
31
+ }) : /* @__PURE__ */ g("div", {
33
32
  className: "min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6 animate-in fade-in duration-200",
34
- children: /* @__PURE__ */ g("div", {
33
+ children: /* @__PURE__ */ _("div", {
35
34
  className: "mx-auto max-w-3xl space-y-6",
36
- children: [/* @__PURE__ */ g("div", {
35
+ children: [/* @__PURE__ */ _("div", {
37
36
  className: "flex items-center gap-3",
38
- children: [/* @__PURE__ */ h(p, {
37
+ children: [/* @__PURE__ */ g(f, {
39
38
  size: 24,
40
39
  className: "text-[var(--color-text-primary)]",
41
40
  "aria-hidden": "true"
42
- }), /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("h1", {
43
- className: "text-2xl font-bold text-[var(--color-text-primary)]",
44
- children: _("members.invitePeople.title", "Invite People")
45
- }), /* @__PURE__ */ h("p", {
46
- className: "mt-1 text-sm text-[var(--color-text-secondary)]",
47
- children: _("members.invitePeople.subtitle", "Pick an organization to send an invite into. You can also invite from any organization or workspace detail page.")
48
- })] })]
49
- }), E.length === 0 ? /* @__PURE__ */ h(m, {
50
- treatment: "plain",
51
- className: "border-border-seam p-6",
52
- children: /* @__PURE__ */ h(a, {
53
- icon: /* @__PURE__ */ h(p, {
54
- size: 40,
55
- "aria-hidden": "true"
41
+ }), /* @__PURE__ */ _("div", { children: [
42
+ /* @__PURE__ */ g("h1", {
43
+ className: "text-2xl font-bold text-[var(--color-text-primary)]",
44
+ children: v("members.invitePeople.title", "Invite People")
56
45
  }),
57
- title: _("members.invitePeople.emptyTitle", "No organizations where you can invite"),
58
- description: _("members.invitePeople.emptyDescription", "You don't currently have permission to invite members into any organization. Ask an organization admin to grant you invite access.")
46
+ /* @__PURE__ */ g("p", {
47
+ className: "mt-1 text-sm text-[var(--color-text-secondary)]",
48
+ children: v("members.invitePeople.subtitle", "Pick an organization to send an invite into. You can also invite from any organization or workspace detail page.")
49
+ }),
50
+ /* @__PURE__ */ g(h, {
51
+ className: "mt-2 max-w-2xl",
52
+ children: v("members.invitePeople.purpose", "This is the quickest way to bring a new person on board — choose which organization to invite them into, then send the invite. They will get an invitation they can accept to join and start collaborating.")
53
+ })
54
+ ] })]
55
+ }), D.length === 0 ? /* @__PURE__ */ g(p, {
56
+ treatment: "glass",
57
+ glow: !0,
58
+ className: "border-border-seam p-6",
59
+ children: /* @__PURE__ */ g(m, {
60
+ illustration: "empty-people",
61
+ title: v("members.invitePeople.emptyTitle", "No organizations where you can invite"),
62
+ description: v("members.invitePeople.emptyDescription", "You don't currently have permission to invite members into any organization. Ask an organization admin to grant you invite access.")
59
63
  })
60
- }) : /* @__PURE__ */ h("ul", {
64
+ }) : /* @__PURE__ */ g("ul", {
61
65
  className: "divide-y divide-[var(--color-border-seam)] overflow-hidden rounded-card border border-border-seam bg-bg-surface shadow-elevation-1",
62
- children: E.map((e) => /* @__PURE__ */ h("li", { children: /* @__PURE__ */ g("button", {
66
+ children: D.map((e) => /* @__PURE__ */ g("li", { children: /* @__PURE__ */ _("button", {
63
67
  type: "button",
64
- onClick: () => v(`${y}/${e.id}/members/invite`),
68
+ onClick: () => y(`${b}/${e.id}/members/invite`),
65
69
  className: "flex w-full items-center justify-between gap-4 px-5 py-4 text-left transition-colors hover:bg-[var(--color-bg-subtle)]",
66
- children: [/* @__PURE__ */ g("div", {
70
+ children: [/* @__PURE__ */ _("div", {
67
71
  className: "flex min-w-0 items-center gap-3",
68
- children: [/* @__PURE__ */ h("div", {
72
+ children: [/* @__PURE__ */ g("div", {
69
73
  className: "flex size-10 items-center justify-center rounded-lg bg-[var(--color-status-info-bgSubtle)] text-[var(--color-status-info-text)]",
70
- children: /* @__PURE__ */ h(d, {
74
+ children: /* @__PURE__ */ g(u, {
71
75
  size: 20,
72
76
  "aria-hidden": "true"
73
77
  })
74
- }), /* @__PURE__ */ g("div", {
78
+ }), /* @__PURE__ */ _("div", {
75
79
  className: "min-w-0",
76
- children: [/* @__PURE__ */ h("p", {
80
+ children: [/* @__PURE__ */ g("p", {
77
81
  className: "truncate text-sm font-semibold text-[var(--color-text-primary)]",
78
82
  children: e.name
79
- }), /* @__PURE__ */ g("p", {
83
+ }), /* @__PURE__ */ _("p", {
80
84
  className: "truncate font-mono text-xs text-[var(--color-text-secondary)]",
81
85
  children: ["/", e.slug]
82
86
  })]
83
87
  })]
84
- }), /* @__PURE__ */ h(f, {
88
+ }), /* @__PURE__ */ g(d, {
85
89
  size: 18,
86
90
  className: "shrink-0 text-[var(--color-text-secondary)]",
87
91
  "aria-hidden": "true"
@@ -92,6 +96,6 @@ function _() {
92
96
  });
93
97
  }
94
98
  //#endregion
95
- export { _ as InvitePeoplePage };
99
+ export { v as InvitePeoplePage };
96
100
 
97
101
  //# sourceMappingURL=InvitePeoplePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"InvitePeoplePage.js","names":[],"sources":["../../../../../src/organization-management/modules/members/pages/InvitePeoplePage.tsx"],"sourcesContent":["import { useEffect, useMemo, useState } from 'react';\nimport { Building, ChevronRight, UserPlus } from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { useOrgConsole } from '../../../providers/OrgConsoleProvider';\nimport { useMyOrganizations } from '../../organizations/hooks/useOrganizations';\nimport { useOrgsWithPermission } from '../../organizations/hooks/useOrgsWithPermission';\nimport { LoadingState } from '../../../shared/components/feedback/LoadingState';\nimport { ErrorState } from '../../../shared/components/feedback/ErrorState';\nimport { EmptyState } from '../../../shared/components/feedback/EmptyState';\nimport { useTr } from '../../../shared/hooks/useTr';\nimport { useOrganizationPageView } from '../../../hooks/useOrganizationPageView';\n\n/**\n * InvitePeoplePage\n *\n * Globally-reachable entry point (sidebar nav item) for inviting users.\n * Lists the orgs the current user can invite into, then deep-links into\n * each org's existing `members/invite` page so the invite flow itself\n * remains a single source of truth.\n *\n * If the user has exactly one org with invite permission, redirect\n * straight to that org's invite page — saves a click for the common case.\n */\nexport function InvitePeoplePage() {\n useOrganizationPageView('organizations.invite-people');\n const tr = useTr();\n const { navigate, basePath = '/organizations' } = useOrgConsole();\n const { organizations, loading, error } = useMyOrganizations(100, 0);\n\n const orgIds = useMemo(() => organizations.map((o) => o.id), [organizations]);\n const {\n allowedIds,\n loading: permLoading,\n isError: permError,\n } = useOrgsWithPermission(orgIds, 'member', 'create');\n\n const invitable = useMemo(\n () => organizations.filter((o) => allowedIds.has(o.id)),\n [organizations, allowedIds]\n );\n\n const [autoRedirected, setAutoRedirected] = useState(false);\n useEffect(() => {\n if (autoRedirected) return;\n if (loading || permLoading) return;\n if (invitable.length === 1) {\n setAutoRedirected(true);\n navigate(`${basePath}/${invitable[0].id}/members/invite`);\n }\n }, [autoRedirected, loading, permLoading, invitable, navigate, basePath]);\n\n if (loading || permLoading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <LoadingState message={tr('common.loading', 'Loading...')} />\n </div>\n );\n }\n\n if (error || permError) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <ErrorState\n message={\n error?.message ||\n tr('members.invitePeople.error', 'Failed to load organizations for invite.')\n }\n />\n </div>\n );\n }\n\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6 animate-in fade-in duration-200\">\n <div className=\"mx-auto max-w-3xl space-y-6\">\n <div className=\"flex items-center gap-3\">\n <UserPlus size={24} className=\"text-[var(--color-text-primary)]\" aria-hidden=\"true\" />\n <div>\n <h1 className=\"text-2xl font-bold text-[var(--color-text-primary)]\">\n {tr('members.invitePeople.title', 'Invite People')}\n </h1>\n <p className=\"mt-1 text-sm text-[var(--color-text-secondary)]\">\n {tr(\n 'members.invitePeople.subtitle',\n 'Pick an organization to send an invite into. You can also invite from any organization or workspace detail page.'\n )}\n </p>\n </div>\n </div>\n\n {invitable.length === 0 ? (\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-6\">\n <EmptyState\n icon={<UserPlus size={40} aria-hidden=\"true\" />}\n title={tr('members.invitePeople.emptyTitle', 'No organizations where you can invite')}\n description={tr(\n 'members.invitePeople.emptyDescription',\n \"You don't currently have permission to invite members into any organization. Ask an organization admin to grant you invite access.\"\n )}\n />\n </GlassCard>\n ) : (\n <ul className=\"divide-y divide-[var(--color-border-seam)] overflow-hidden rounded-card border border-border-seam bg-bg-surface shadow-elevation-1\">\n {invitable.map((org) => (\n <li key={org.id}>\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/${org.id}/members/invite`)}\n className=\"flex w-full items-center justify-between gap-4 px-5 py-4 text-left transition-colors hover:bg-[var(--color-bg-subtle)]\"\n >\n <div className=\"flex min-w-0 items-center gap-3\">\n <div className=\"flex size-10 items-center justify-center rounded-lg bg-[var(--color-status-info-bgSubtle)] text-[var(--color-status-info-text)]\">\n <Building size={20} aria-hidden=\"true\" />\n </div>\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-semibold text-[var(--color-text-primary)]\">\n {org.name}\n </p>\n <p className=\"truncate font-mono text-xs text-[var(--color-text-secondary)]\">\n /{org.slug}\n </p>\n </div>\n </div>\n <ChevronRight\n size={18}\n className=\"shrink-0 text-[var(--color-text-secondary)]\"\n aria-hidden=\"true\"\n />\n </button>\n </li>\n ))}\n </ul>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAuBA,SAAgB,IAAmB;AACjC,GAAwB,8BAA8B;CACtD,IAAM,IAAK,GAAO,EACZ,EAAE,aAAU,cAAW,qBAAqB,GAAe,EAC3D,EAAE,kBAAe,YAAS,aAAU,EAAmB,KAAK,EAAE,EAG9D,EACJ,eACA,SAAS,GACT,SAAS,MACP,EALW,QAAc,EAAc,KAAK,MAAM,EAAE,GAAG,EAAE,CAAC,EAAc,CAAC,EAK3C,UAAU,SAAS,EAE/C,IAAY,QACV,EAAc,QAAQ,MAAM,EAAW,IAAI,EAAE,GAAG,CAAC,EACvD,CAAC,GAAe,EAAW,CAC5B,EAEK,CAAC,GAAgB,KAAqB,EAAS,GAAM;AA+B3D,QA9BA,QAAgB;AACV,OACA,KAAW,KACX,EAAU,WAAW,MACvB,EAAkB,GAAK,EACvB,EAAS,GAAG,EAAS,GAAG,EAAU,GAAG,GAAG,iBAAiB;IAE1D;EAAC;EAAgB;EAAS;EAAa;EAAW;EAAU;EAAS,CAAC,EAErE,KAAW,IAEX,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD,EAAc,SAAS,EAAG,kBAAkB,aAAa,EAAI,CAAA;EACzD,CAAA,GAIN,KAAS,IAET,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD,EACE,SACE,GAAO,WACP,EAAG,8BAA8B,2CAA2C,EAE9E,CAAA;EACE,CAAA,GAKR,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KAAU,MAAM;KAAI,WAAU;KAAmC,eAAY;KAAS,CAAA,EACtF,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;KAAI,WAAU;eACX,EAAG,8BAA8B,gBAAgB;KAC/C,CAAA,EACL,kBAAC,KAAD;KAAG,WAAU;eACV,EACC,iCACA,mHACD;KACC,CAAA,CACA,EAAA,CAAA,CACF;OAEL,EAAU,WAAW,IACpB,kBAAC,GAAD;IAAW,WAAU;IAAQ,WAAU;cACrC,kBAAC,GAAD;KACE,MAAM,kBAAC,GAAD;MAAU,MAAM;MAAI,eAAY;MAAS,CAAA;KAC/C,OAAO,EAAG,mCAAmC,wCAAwC;KACrF,aAAa,EACX,yCACA,qIACD;KACD,CAAA;IACQ,CAAA,GAEZ,kBAAC,MAAD;IAAI,WAAU;cACX,EAAU,KAAK,MACd,kBAAC,MAAD,EAAA,UACE,kBAAC,UAAD;KACE,MAAK;KACL,eAAe,EAAS,GAAG,EAAS,GAAG,EAAI,GAAG,iBAAiB;KAC/D,WAAU;eAHZ,CAKE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD;QAAU,MAAM;QAAI,eAAY;QAAS,CAAA;OACrC,CAAA,EACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAI;QACH,CAAA,EACJ,kBAAC,KAAD;QAAG,WAAU;kBAAb,CAA6E,KACzE,EAAI,KACJ;UACA;SACF;SACN,kBAAC,GAAD;MACE,MAAM;MACN,WAAU;MACV,eAAY;MACZ,CAAA,CACK;QACN,EAzBI,EAAI,GAyBR,CACL;IACC,CAAA,CAEH;;EACF,CAAA"}
1
+ {"version":3,"file":"InvitePeoplePage.js","names":[],"sources":["../../../../../src/organization-management/modules/members/pages/InvitePeoplePage.tsx"],"sourcesContent":["import { useEffect, useMemo, useState } from 'react';\nimport { Building, ChevronRight, UserPlus } from 'lucide-react';\nimport { GlassCard, IllustratedEmptyState, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { useOrgConsole } from '../../../providers/OrgConsoleProvider';\nimport { useMyOrganizations } from '../../organizations/hooks/useOrganizations';\nimport { useOrgsWithPermission } from '../../organizations/hooks/useOrgsWithPermission';\nimport { LoadingState } from '../../../shared/components/feedback/LoadingState';\nimport { ErrorState } from '../../../shared/components/feedback/ErrorState';\nimport { useTr } from '../../../shared/hooks/useTr';\nimport { useOrganizationPageView } from '../../../hooks/useOrganizationPageView';\n\n/**\n * InvitePeoplePage\n *\n * Globally-reachable entry point (sidebar nav item) for inviting users.\n * Lists the orgs the current user can invite into, then deep-links into\n * each org's existing `members/invite` page so the invite flow itself\n * remains a single source of truth.\n *\n * If the user has exactly one org with invite permission, redirect\n * straight to that org's invite page — saves a click for the common case.\n */\nexport function InvitePeoplePage() {\n useOrganizationPageView('organizations.invite-people');\n const tr = useTr();\n const { navigate, basePath = '/organizations' } = useOrgConsole();\n const { organizations, loading, error } = useMyOrganizations(100, 0);\n\n const orgIds = useMemo(() => organizations.map((o) => o.id), [organizations]);\n const {\n allowedIds,\n loading: permLoading,\n isError: permError,\n } = useOrgsWithPermission(orgIds, 'member', 'create');\n\n const invitable = useMemo(\n () => organizations.filter((o) => allowedIds.has(o.id)),\n [organizations, allowedIds]\n );\n\n const [autoRedirected, setAutoRedirected] = useState(false);\n useEffect(() => {\n if (autoRedirected) return;\n if (loading || permLoading) return;\n if (invitable.length === 1) {\n setAutoRedirected(true);\n navigate(`${basePath}/${invitable[0].id}/members/invite`);\n }\n }, [autoRedirected, loading, permLoading, invitable, navigate, basePath]);\n\n if (loading || permLoading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <LoadingState message={tr('common.loading', 'Loading...')} />\n </div>\n );\n }\n\n if (error || permError) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <ErrorState\n message={\n error?.message ||\n tr('members.invitePeople.error', 'Failed to load organizations for invite.')\n }\n />\n </div>\n );\n }\n\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6 animate-in fade-in duration-200\">\n <div className=\"mx-auto max-w-3xl space-y-6\">\n <div className=\"flex items-center gap-3\">\n <UserPlus size={24} className=\"text-[var(--color-text-primary)]\" aria-hidden=\"true\" />\n <div>\n <h1 className=\"text-2xl font-bold text-[var(--color-text-primary)]\">\n {tr('members.invitePeople.title', 'Invite People')}\n </h1>\n <p className=\"mt-1 text-sm text-[var(--color-text-secondary)]\">\n {tr(\n 'members.invitePeople.subtitle',\n 'Pick an organization to send an invite into. You can also invite from any organization or workspace detail page.'\n )}\n </p>\n <PagePurpose className=\"mt-2 max-w-2xl\">\n {tr(\n 'members.invitePeople.purpose',\n 'This is the quickest way to bring a new person on board — choose which organization to invite them into, then send the invite. They will get an invitation they can accept to join and start collaborating.'\n )}\n </PagePurpose>\n </div>\n </div>\n\n {invitable.length === 0 ? (\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam p-6\">\n <IllustratedEmptyState\n illustration=\"empty-people\"\n title={tr('members.invitePeople.emptyTitle', 'No organizations where you can invite')}\n description={tr(\n 'members.invitePeople.emptyDescription',\n \"You don't currently have permission to invite members into any organization. Ask an organization admin to grant you invite access.\"\n )}\n />\n </GlassCard>\n ) : (\n <ul className=\"divide-y divide-[var(--color-border-seam)] overflow-hidden rounded-card border border-border-seam bg-bg-surface shadow-elevation-1\">\n {invitable.map((org) => (\n <li key={org.id}>\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/${org.id}/members/invite`)}\n className=\"flex w-full items-center justify-between gap-4 px-5 py-4 text-left transition-colors hover:bg-[var(--color-bg-subtle)]\"\n >\n <div className=\"flex min-w-0 items-center gap-3\">\n <div className=\"flex size-10 items-center justify-center rounded-lg bg-[var(--color-status-info-bgSubtle)] text-[var(--color-status-info-text)]\">\n <Building size={20} aria-hidden=\"true\" />\n </div>\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-semibold text-[var(--color-text-primary)]\">\n {org.name}\n </p>\n <p className=\"truncate font-mono text-xs text-[var(--color-text-secondary)]\">\n /{org.slug}\n </p>\n </div>\n </div>\n <ChevronRight\n size={18}\n className=\"shrink-0 text-[var(--color-text-secondary)]\"\n aria-hidden=\"true\"\n />\n </button>\n </li>\n ))}\n </ul>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAsBA,SAAgB,IAAmB;AACjC,GAAwB,8BAA8B;CACtD,IAAM,IAAK,GAAO,EACZ,EAAE,aAAU,cAAW,qBAAqB,GAAe,EAC3D,EAAE,kBAAe,YAAS,aAAU,EAAmB,KAAK,EAAE,EAG9D,EACJ,eACA,SAAS,GACT,SAAS,MACP,EALW,QAAc,EAAc,KAAK,MAAM,EAAE,GAAG,EAAE,CAAC,EAAc,CAAC,EAK3C,UAAU,SAAS,EAE/C,IAAY,QACV,EAAc,QAAQ,MAAM,EAAW,IAAI,EAAE,GAAG,CAAC,EACvD,CAAC,GAAe,EAAW,CAC5B,EAEK,CAAC,GAAgB,KAAqB,EAAS,GAAM;AA+B3D,QA9BA,QAAgB;AACV,OACA,KAAW,KACX,EAAU,WAAW,MACvB,EAAkB,GAAK,EACvB,EAAS,GAAG,EAAS,GAAG,EAAU,GAAG,GAAG,iBAAiB;IAE1D;EAAC;EAAgB;EAAS;EAAa;EAAW;EAAU;EAAS,CAAC,EAErE,KAAW,IAEX,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD,EAAc,SAAS,EAAG,kBAAkB,aAAa,EAAI,CAAA;EACzD,CAAA,GAIN,KAAS,IAET,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD,EACE,SACE,GAAO,WACP,EAAG,8BAA8B,2CAA2C,EAE9E,CAAA;EACE,CAAA,GAKR,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KAAU,MAAM;KAAI,WAAU;KAAmC,eAAY;KAAS,CAAA,EACtF,kBAAC,OAAD,EAAA,UAAA;KACE,kBAAC,MAAD;MAAI,WAAU;gBACX,EAAG,8BAA8B,gBAAgB;MAC/C,CAAA;KACL,kBAAC,KAAD;MAAG,WAAU;gBACV,EACC,iCACA,mHACD;MACC,CAAA;KACJ,kBAAC,GAAD;MAAa,WAAU;gBACpB,EACC,gCACA,8MACD;MACW,CAAA;KACV,EAAA,CAAA,CACF;OAEL,EAAU,WAAW,IACpB,kBAAC,GAAD;IAAW,WAAU;IAAQ,MAAA;IAAK,WAAU;cAC1C,kBAAC,GAAD;KACE,cAAa;KACb,OAAO,EAAG,mCAAmC,wCAAwC;KACrF,aAAa,EACX,yCACA,qIACD;KACD,CAAA;IACQ,CAAA,GAEZ,kBAAC,MAAD;IAAI,WAAU;cACX,EAAU,KAAK,MACd,kBAAC,MAAD,EAAA,UACE,kBAAC,UAAD;KACE,MAAK;KACL,eAAe,EAAS,GAAG,EAAS,GAAG,EAAI,GAAG,iBAAiB;KAC/D,WAAU;eAHZ,CAKE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD;QAAU,MAAM;QAAI,eAAY;QAAS,CAAA;OACrC,CAAA,EACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAI;QACH,CAAA,EACJ,kBAAC,KAAD;QAAG,WAAU;kBAAb,CAA6E,KACzE,EAAI,KACJ;UACA;SACF;SACN,kBAAC,GAAD;MACE,MAAM;MACN,WAAU;MACV,eAAY;MACZ,CAAA,CACK;QACN,EAzBI,EAAI,GAyBR,CACL;IACC,CAAA,CAEH;;EACF,CAAA"}