@burdenoff/microfe-workspaces 2026.510.50

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 (260) hide show
  1. package/README.md +88 -0
  2. package/dist/WorkspacesRoot.d.ts +35 -0
  3. package/dist/WorkspacesRoot.d.ts.map +1 -0
  4. package/dist/WorkspacesRoot.js +71 -0
  5. package/dist/WorkspacesRoot.js.map +1 -0
  6. package/dist/WorkspacesRoutes.d.ts +10 -0
  7. package/dist/WorkspacesRoutes.d.ts.map +1 -0
  8. package/dist/WorkspacesRoutes.js +111 -0
  9. package/dist/WorkspacesRoutes.js.map +1 -0
  10. package/dist/components/CreateProjectDialog.d.ts +6 -0
  11. package/dist/components/CreateProjectDialog.d.ts.map +1 -0
  12. package/dist/components/CreateProjectDialog.js +115 -0
  13. package/dist/components/CreateProjectDialog.js.map +1 -0
  14. package/dist/components/CreateWorkspaceDialog.d.ts +2 -0
  15. package/dist/components/CreateWorkspaceDialog.d.ts.map +1 -0
  16. package/dist/components/CreateWorkspaceDialog.js +172 -0
  17. package/dist/components/CreateWorkspaceDialog.js.map +1 -0
  18. package/dist/components/InviteMemberDialog.d.ts +7 -0
  19. package/dist/components/InviteMemberDialog.d.ts.map +1 -0
  20. package/dist/components/InviteMemberDialog.js +148 -0
  21. package/dist/components/InviteMemberDialog.js.map +1 -0
  22. package/dist/components/MemberListItem.d.ts +11 -0
  23. package/dist/components/MemberListItem.d.ts.map +1 -0
  24. package/dist/components/MemberListItem.js +118 -0
  25. package/dist/components/MemberListItem.js.map +1 -0
  26. package/dist/components/ProjectCard.d.ts +13 -0
  27. package/dist/components/ProjectCard.d.ts.map +1 -0
  28. package/dist/components/ProjectCard.js +150 -0
  29. package/dist/components/ProjectCard.js.map +1 -0
  30. package/dist/components/WorkspaceCard.d.ts +8 -0
  31. package/dist/components/WorkspaceCard.d.ts.map +1 -0
  32. package/dist/components/WorkspaceCard.js +79 -0
  33. package/dist/components/WorkspaceCard.js.map +1 -0
  34. package/dist/components/WorkspacesErrorBoundary.d.ts +27 -0
  35. package/dist/components/WorkspacesErrorBoundary.d.ts.map +1 -0
  36. package/dist/components/WorkspacesErrorBoundary.js +136 -0
  37. package/dist/components/WorkspacesErrorBoundary.js.map +1 -0
  38. package/dist/components/index.d.ts +8 -0
  39. package/dist/components/index.d.ts.map +1 -0
  40. package/dist/components/index.js +7 -0
  41. package/dist/constants/permissions.d.ts +33 -0
  42. package/dist/constants/permissions.d.ts.map +1 -0
  43. package/dist/constants/permissions.js +31 -0
  44. package/dist/constants/permissions.js.map +1 -0
  45. package/dist/generated/global-operations.d.ts +279 -0
  46. package/dist/generated/global-operations.d.ts.map +1 -0
  47. package/dist/generated/global-operations.js +103 -0
  48. package/dist/generated/global-operations.js.map +1 -0
  49. package/dist/generated/global-types.d.ts +20714 -0
  50. package/dist/generated/global-types.d.ts.map +1 -0
  51. package/dist/generated/wspace-operations.d.ts +2209 -0
  52. package/dist/generated/wspace-operations.d.ts.map +1 -0
  53. package/dist/generated/wspace-operations.js +576 -0
  54. package/dist/generated/wspace-operations.js.map +1 -0
  55. package/dist/generated/wspace-types.d.ts +54990 -0
  56. package/dist/generated/wspace-types.d.ts.map +1 -0
  57. package/dist/hooks/index.d.ts +8 -0
  58. package/dist/hooks/index.d.ts.map +1 -0
  59. package/dist/hooks/index.js +7 -0
  60. package/dist/hooks/useMemberMutations.d.ts +61 -0
  61. package/dist/hooks/useMemberMutations.d.ts.map +1 -0
  62. package/dist/hooks/useMemberMutations.js +263 -0
  63. package/dist/hooks/useMemberMutations.js.map +1 -0
  64. package/dist/hooks/useProjectMutations.d.ts +26 -0
  65. package/dist/hooks/useProjectMutations.d.ts.map +1 -0
  66. package/dist/hooks/useProjectMutations.js +127 -0
  67. package/dist/hooks/useProjectMutations.js.map +1 -0
  68. package/dist/hooks/useProjects.d.ts +16 -0
  69. package/dist/hooks/useProjects.d.ts.map +1 -0
  70. package/dist/hooks/useProjects.js +103 -0
  71. package/dist/hooks/useProjects.js.map +1 -0
  72. package/dist/hooks/useScopedNavigation.d.ts +4 -0
  73. package/dist/hooks/useScopedNavigation.d.ts.map +1 -0
  74. package/dist/hooks/useScopedNavigation.js +11 -0
  75. package/dist/hooks/useScopedNavigation.js.map +1 -0
  76. package/dist/hooks/useTenants.d.ts +13 -0
  77. package/dist/hooks/useTenants.d.ts.map +1 -0
  78. package/dist/hooks/useTenants.js +47 -0
  79. package/dist/hooks/useTenants.js.map +1 -0
  80. package/dist/hooks/useWorkspaceActivity.d.ts +12 -0
  81. package/dist/hooks/useWorkspaceActivity.d.ts.map +1 -0
  82. package/dist/hooks/useWorkspaceActivity.js +31 -0
  83. package/dist/hooks/useWorkspaceActivity.js.map +1 -0
  84. package/dist/hooks/useWorkspaceMembers.d.ts +24 -0
  85. package/dist/hooks/useWorkspaceMembers.d.ts.map +1 -0
  86. package/dist/hooks/useWorkspaceMembers.js +130 -0
  87. package/dist/hooks/useWorkspaceMembers.js.map +1 -0
  88. package/dist/hooks/useWorkspaceMutations.d.ts +36 -0
  89. package/dist/hooks/useWorkspaceMutations.d.ts.map +1 -0
  90. package/dist/hooks/useWorkspaceMutations.js +119 -0
  91. package/dist/hooks/useWorkspaceMutations.js.map +1 -0
  92. package/dist/hooks/useWorkspacePermissions.d.ts +29 -0
  93. package/dist/hooks/useWorkspacePermissions.d.ts.map +1 -0
  94. package/dist/hooks/useWorkspacePermissions.js +33 -0
  95. package/dist/hooks/useWorkspacePermissions.js.map +1 -0
  96. package/dist/hooks/useWorkspaceRoles.d.ts +8 -0
  97. package/dist/hooks/useWorkspaceRoles.d.ts.map +1 -0
  98. package/dist/hooks/useWorkspaceRoles.js +31 -0
  99. package/dist/hooks/useWorkspaceRoles.js.map +1 -0
  100. package/dist/hooks/useWorkspaces.d.ts +21 -0
  101. package/dist/hooks/useWorkspaces.d.ts.map +1 -0
  102. package/dist/hooks/useWorkspaces.js +75 -0
  103. package/dist/hooks/useWorkspaces.js.map +1 -0
  104. package/dist/hooks/useWorkspacesEventEmitter.d.ts +14 -0
  105. package/dist/hooks/useWorkspacesEventEmitter.d.ts.map +1 -0
  106. package/dist/hooks/useWorkspacesEventEmitter.js +14 -0
  107. package/dist/hooks/useWorkspacesEventEmitter.js.map +1 -0
  108. package/dist/index.d.ts +33 -0
  109. package/dist/index.d.ts.map +1 -0
  110. package/dist/index.js +24 -0
  111. package/dist/pages/ActivityListPage.d.ts +2 -0
  112. package/dist/pages/ActivityListPage.d.ts.map +1 -0
  113. package/dist/pages/ActivityListPage.js +119 -0
  114. package/dist/pages/ActivityListPage.js.map +1 -0
  115. package/dist/pages/CreateWorkspacePage.d.ts +2 -0
  116. package/dist/pages/CreateWorkspacePage.d.ts.map +1 -0
  117. package/dist/pages/CreateWorkspacePage.js +264 -0
  118. package/dist/pages/CreateWorkspacePage.js.map +1 -0
  119. package/dist/pages/InviteAcceptancePage.d.ts +6 -0
  120. package/dist/pages/InviteAcceptancePage.d.ts.map +1 -0
  121. package/dist/pages/InviteAcceptancePage.js +495 -0
  122. package/dist/pages/InviteAcceptancePage.js.map +1 -0
  123. package/dist/pages/MembersListPage.d.ts +2 -0
  124. package/dist/pages/MembersListPage.d.ts.map +1 -0
  125. package/dist/pages/MembersListPage.js +420 -0
  126. package/dist/pages/MembersListPage.js.map +1 -0
  127. package/dist/pages/ProjectDetailPage.d.ts +2 -0
  128. package/dist/pages/ProjectDetailPage.d.ts.map +1 -0
  129. package/dist/pages/ProjectDetailPage.js +361 -0
  130. package/dist/pages/ProjectDetailPage.js.map +1 -0
  131. package/dist/pages/ProjectsListPage.d.ts +2 -0
  132. package/dist/pages/ProjectsListPage.d.ts.map +1 -0
  133. package/dist/pages/ProjectsListPage.js +398 -0
  134. package/dist/pages/ProjectsListPage.js.map +1 -0
  135. package/dist/pages/WorkspaceDetailPage.d.ts +2 -0
  136. package/dist/pages/WorkspaceDetailPage.d.ts.map +1 -0
  137. package/dist/pages/WorkspaceDetailPage.js +230 -0
  138. package/dist/pages/WorkspaceDetailPage.js.map +1 -0
  139. package/dist/pages/WorkspaceSettingsPage.d.ts +2 -0
  140. package/dist/pages/WorkspaceSettingsPage.d.ts.map +1 -0
  141. package/dist/pages/WorkspaceSettingsPage.js +157 -0
  142. package/dist/pages/WorkspaceSettingsPage.js.map +1 -0
  143. package/dist/pages/WorkspacesListPage.d.ts +2 -0
  144. package/dist/pages/WorkspacesListPage.d.ts.map +1 -0
  145. package/dist/pages/WorkspacesListPage.js +186 -0
  146. package/dist/pages/WorkspacesListPage.js.map +1 -0
  147. package/dist/pages/dashboard/DashboardCustomizer.d.ts +12 -0
  148. package/dist/pages/dashboard/DashboardCustomizer.d.ts.map +1 -0
  149. package/dist/pages/dashboard/DashboardCustomizer.js +136 -0
  150. package/dist/pages/dashboard/DashboardCustomizer.js.map +1 -0
  151. package/dist/pages/dashboard/DashboardGrid.d.ts +8 -0
  152. package/dist/pages/dashboard/DashboardGrid.d.ts.map +1 -0
  153. package/dist/pages/dashboard/DashboardGrid.js +58 -0
  154. package/dist/pages/dashboard/DashboardGrid.js.map +1 -0
  155. package/dist/pages/dashboard/DashboardPage.d.ts +14 -0
  156. package/dist/pages/dashboard/DashboardPage.d.ts.map +1 -0
  157. package/dist/pages/dashboard/DashboardPage.js +136 -0
  158. package/dist/pages/dashboard/DashboardPage.js.map +1 -0
  159. package/dist/pages/dashboard/WidgetWrapper.d.ts +17 -0
  160. package/dist/pages/dashboard/WidgetWrapper.d.ts.map +1 -0
  161. package/dist/pages/dashboard/WidgetWrapper.js +72 -0
  162. package/dist/pages/dashboard/WidgetWrapper.js.map +1 -0
  163. package/dist/pages/dashboard/config.d.ts +9 -0
  164. package/dist/pages/dashboard/config.d.ts.map +1 -0
  165. package/dist/pages/dashboard/config.js +214 -0
  166. package/dist/pages/dashboard/config.js.map +1 -0
  167. package/dist/pages/dashboard/hooks/useDashboardData.d.ts +9 -0
  168. package/dist/pages/dashboard/hooks/useDashboardData.d.ts.map +1 -0
  169. package/dist/pages/dashboard/hooks/useDashboardData.js +118 -0
  170. package/dist/pages/dashboard/hooks/useDashboardData.js.map +1 -0
  171. package/dist/pages/dashboard/hooks/useDashboardPreferences.d.ts +4 -0
  172. package/dist/pages/dashboard/hooks/useDashboardPreferences.d.ts.map +1 -0
  173. package/dist/pages/dashboard/hooks/useDashboardPreferences.js +32 -0
  174. package/dist/pages/dashboard/hooks/useDashboardPreferences.js.map +1 -0
  175. package/dist/pages/dashboard/types.d.ts +145 -0
  176. package/dist/pages/dashboard/types.d.ts.map +1 -0
  177. package/dist/pages/dashboard/widgets/GroupsWidget.d.ts +4 -0
  178. package/dist/pages/dashboard/widgets/GroupsWidget.d.ts.map +1 -0
  179. package/dist/pages/dashboard/widgets/GroupsWidget.js +59 -0
  180. package/dist/pages/dashboard/widgets/GroupsWidget.js.map +1 -0
  181. package/dist/pages/dashboard/widgets/MembersWidget.d.ts +4 -0
  182. package/dist/pages/dashboard/widgets/MembersWidget.d.ts.map +1 -0
  183. package/dist/pages/dashboard/widgets/MembersWidget.js +65 -0
  184. package/dist/pages/dashboard/widgets/MembersWidget.js.map +1 -0
  185. package/dist/pages/dashboard/widgets/ProjectsWidget.d.ts +4 -0
  186. package/dist/pages/dashboard/widgets/ProjectsWidget.d.ts.map +1 -0
  187. package/dist/pages/dashboard/widgets/ProjectsWidget.js +91 -0
  188. package/dist/pages/dashboard/widgets/ProjectsWidget.js.map +1 -0
  189. package/dist/pages/dashboard/widgets/QuickActionsWidget.d.ts +4 -0
  190. package/dist/pages/dashboard/widgets/QuickActionsWidget.d.ts.map +1 -0
  191. package/dist/pages/dashboard/widgets/QuickActionsWidget.js +80 -0
  192. package/dist/pages/dashboard/widgets/QuickActionsWidget.js.map +1 -0
  193. package/dist/pages/dashboard/widgets/RecentActivityWidget.d.ts +4 -0
  194. package/dist/pages/dashboard/widgets/RecentActivityWidget.d.ts.map +1 -0
  195. package/dist/pages/dashboard/widgets/RecentActivityWidget.js +81 -0
  196. package/dist/pages/dashboard/widgets/RecentActivityWidget.js.map +1 -0
  197. package/dist/pages/dashboard/widgets/StorageWidget.d.ts +4 -0
  198. package/dist/pages/dashboard/widgets/StorageWidget.d.ts.map +1 -0
  199. package/dist/pages/dashboard/widgets/StorageWidget.js +69 -0
  200. package/dist/pages/dashboard/widgets/StorageWidget.js.map +1 -0
  201. package/dist/pages/dashboard/widgets/SystemHealthWidget.d.ts +4 -0
  202. package/dist/pages/dashboard/widgets/SystemHealthWidget.d.ts.map +1 -0
  203. package/dist/pages/dashboard/widgets/SystemHealthWidget.js +59 -0
  204. package/dist/pages/dashboard/widgets/SystemHealthWidget.js.map +1 -0
  205. package/dist/pages/dashboard/widgets/TagCloudWidget.d.ts +4 -0
  206. package/dist/pages/dashboard/widgets/TagCloudWidget.d.ts.map +1 -0
  207. package/dist/pages/dashboard/widgets/TagCloudWidget.js +61 -0
  208. package/dist/pages/dashboard/widgets/TagCloudWidget.js.map +1 -0
  209. package/dist/pages/dashboard/widgets/TipsWidget.d.ts +4 -0
  210. package/dist/pages/dashboard/widgets/TipsWidget.d.ts.map +1 -0
  211. package/dist/pages/dashboard/widgets/TipsWidget.js +67 -0
  212. package/dist/pages/dashboard/widgets/TipsWidget.js.map +1 -0
  213. package/dist/pages/dashboard/widgets/UpcomingEventsWidget.d.ts +4 -0
  214. package/dist/pages/dashboard/widgets/UpcomingEventsWidget.d.ts.map +1 -0
  215. package/dist/pages/dashboard/widgets/UpcomingEventsWidget.js +83 -0
  216. package/dist/pages/dashboard/widgets/UpcomingEventsWidget.js.map +1 -0
  217. package/dist/pages/dashboard/widgets/WelcomeWidget.d.ts +4 -0
  218. package/dist/pages/dashboard/widgets/WelcomeWidget.d.ts.map +1 -0
  219. package/dist/pages/dashboard/widgets/WelcomeWidget.js +71 -0
  220. package/dist/pages/dashboard/widgets/WelcomeWidget.js.map +1 -0
  221. package/dist/pages/dashboard/widgets/WorkflowStatsWidget.d.ts +4 -0
  222. package/dist/pages/dashboard/widgets/WorkflowStatsWidget.d.ts.map +1 -0
  223. package/dist/pages/dashboard/widgets/WorkflowStatsWidget.js +97 -0
  224. package/dist/pages/dashboard/widgets/WorkflowStatsWidget.js.map +1 -0
  225. package/dist/pages/dashboard/widgets/WorkspacesWidget.d.ts +4 -0
  226. package/dist/pages/dashboard/widgets/WorkspacesWidget.d.ts.map +1 -0
  227. package/dist/pages/dashboard/widgets/WorkspacesWidget.js +67 -0
  228. package/dist/pages/dashboard/widgets/WorkspacesWidget.js.map +1 -0
  229. package/dist/providers/WorkspacesProvider.d.ts +13 -0
  230. package/dist/providers/WorkspacesProvider.d.ts.map +1 -0
  231. package/dist/providers/WorkspacesProvider.js +24 -0
  232. package/dist/providers/WorkspacesProvider.js.map +1 -0
  233. package/dist/store/workspacesStore.d.ts +82 -0
  234. package/dist/store/workspacesStore.d.ts.map +1 -0
  235. package/dist/store/workspacesStore.js +92 -0
  236. package/dist/store/workspacesStore.js.map +1 -0
  237. package/dist/types/index.d.ts +280 -0
  238. package/dist/types/index.d.ts.map +1 -0
  239. package/dist/utils/formatters.d.ts +60 -0
  240. package/dist/utils/formatters.d.ts.map +1 -0
  241. package/dist/utils/formatters.js +61 -0
  242. package/dist/utils/formatters.js.map +1 -0
  243. package/dist/utils/index.d.ts +3 -0
  244. package/dist/utils/index.d.ts.map +1 -0
  245. package/dist/utils/nativeBridge.d.ts +3 -0
  246. package/dist/utils/nativeBridge.d.ts.map +1 -0
  247. package/dist/utils/nativeBridge.js +2 -0
  248. package/dist/utils/projectTags.d.ts +6 -0
  249. package/dist/utils/projectTags.d.ts.map +1 -0
  250. package/dist/utils/projectTags.js +49 -0
  251. package/dist/utils/projectTags.js.map +1 -0
  252. package/dist/utils/slug.d.ts +13 -0
  253. package/dist/utils/slug.d.ts.map +1 -0
  254. package/dist/utils/slug.js +8 -0
  255. package/dist/utils/slug.js.map +1 -0
  256. package/dist/utils/tokenHelpers.d.ts +114 -0
  257. package/dist/utils/tokenHelpers.d.ts.map +1 -0
  258. package/dist/utils/tokenHelpers.js +80 -0
  259. package/dist/utils/tokenHelpers.js.map +1 -0
  260. package/package.json +113 -0
@@ -0,0 +1,172 @@
1
+ import { useWorkspacesStore as e } from "../store/workspacesStore.js";
2
+ import { useCreateWorkspace as t } from "../hooks/useWorkspaceMutations.js";
3
+ import { useMyOrganizations as n, useMyTenants as r } from "../hooks/useTenants.js";
4
+ import { generateSlug as i } from "../utils/slug.js";
5
+ import { useEffect as a, useMemo as o } from "react";
6
+ import { AlertCircle as s } from "lucide-react";
7
+ import { jsx as c, jsxs as l } from "react/jsx-runtime";
8
+ import { Button as u, Dialog as d, DialogContent as f, DialogFooter as p, DialogHeader as m, DialogTitle as h, Skeleton as g } from "@burdenoff/fe-libs/ui";
9
+ import { FormControl as _, FormDescription as v, FormField as y, FormItem as b, FormLabel as x, FormMessage as S, FormProvider as C, Input as w, Select as T, SelectContent as E, SelectItem as D, SelectTrigger as O, SelectValue as k, useForm as A, z as j } from "@burdenoff/fe-libs/form";
10
+ //#region src/components/CreateWorkspaceDialog.tsx
11
+ var M = j.object({
12
+ name: j.string().min(2, "Name must be at least 2 characters").max(100),
13
+ slug: j.string().min(2, "Slug must be at least 2 characters").max(50).regex(/^[a-z0-9-]+$/, "Slug can only contain lowercase letters, numbers, and hyphens"),
14
+ tenantId: j.string().min(1, "Please select a tenant"),
15
+ organizationId: j.string().min(1, "Please select an organization"),
16
+ type: j.enum(["TEAM", "PERSONAL"]).optional()
17
+ });
18
+ function N() {
19
+ let { isCreateWorkspaceDialogOpen: j, closeCreateWorkspaceDialog: N } = e(), { mutate: P, isPending: F } = t(), { data: I, isLoading: L, error: R } = r(), { data: z, isLoading: B, error: V } = n(), H = I?.items ?? [], U = z?.items ?? [], W = A({
20
+ schema: M,
21
+ defaultValues: {
22
+ name: "",
23
+ slug: "",
24
+ tenantId: "",
25
+ organizationId: "",
26
+ type: "TEAM"
27
+ }
28
+ }), G = W.watch("tenantId"), K = W.watch("name"), q = o(() => G ? U.filter((e) => e.tenantId === G) : [], [G, U]);
29
+ a(() => {
30
+ W.setValue("slug", K ? i(K) : "");
31
+ }, [K, W]), a(() => {
32
+ W.setValue("organizationId", "");
33
+ }, [G, W]);
34
+ let J = (e) => {
35
+ P({
36
+ name: e.name,
37
+ slug: e.slug,
38
+ tenantId: e.tenantId,
39
+ organizationId: e.organizationId,
40
+ type: e.type
41
+ }, { onSuccess: () => {
42
+ N(), W.reset();
43
+ } });
44
+ };
45
+ return /* @__PURE__ */ c(d, {
46
+ open: j,
47
+ onOpenChange: N,
48
+ children: /* @__PURE__ */ l(f, {
49
+ className: "sm:max-w-[500px]",
50
+ children: [/* @__PURE__ */ c(m, { children: /* @__PURE__ */ c(h, { children: "Create Workspace" }) }), /* @__PURE__ */ c(C, {
51
+ ...W,
52
+ children: /* @__PURE__ */ l("form", {
53
+ onSubmit: W.handleSubmit(J),
54
+ className: "space-y-4",
55
+ children: [
56
+ /* @__PURE__ */ c(y, {
57
+ control: W.control,
58
+ name: "name",
59
+ render: ({ field: e }) => /* @__PURE__ */ l(b, { children: [
60
+ /* @__PURE__ */ c(x, { children: "Workspace Name *" }),
61
+ /* @__PURE__ */ c(_, { children: /* @__PURE__ */ c(w, {
62
+ placeholder: "My Workspace",
63
+ ...e
64
+ }) }),
65
+ /* @__PURE__ */ c(v, { children: "A descriptive name for your workspace" }),
66
+ /* @__PURE__ */ c(S, {})
67
+ ] })
68
+ }),
69
+ /* @__PURE__ */ c(y, {
70
+ control: W.control,
71
+ name: "slug",
72
+ render: ({ field: e }) => /* @__PURE__ */ l(b, { children: [
73
+ /* @__PURE__ */ c(x, { children: "Slug *" }),
74
+ /* @__PURE__ */ c(_, { children: /* @__PURE__ */ c(w, {
75
+ placeholder: "my-workspace",
76
+ ...e
77
+ }) }),
78
+ /* @__PURE__ */ c(v, { children: "URL-friendly identifier (auto-generated)" }),
79
+ /* @__PURE__ */ c(S, {})
80
+ ] })
81
+ }),
82
+ /* @__PURE__ */ c(y, {
83
+ control: W.control,
84
+ name: "tenantId",
85
+ render: ({ field: e }) => /* @__PURE__ */ l(b, { children: [
86
+ /* @__PURE__ */ c(x, { children: "Tenant *" }),
87
+ L ? /* @__PURE__ */ c(g, { className: "h-10 w-full" }) : R ? /* @__PURE__ */ l("div", {
88
+ className: "flex items-center gap-2 text-destructive text-sm",
89
+ children: [/* @__PURE__ */ c(s, { size: 16 }), "Failed to load tenants"]
90
+ }) : H.length === 0 ? /* @__PURE__ */ c("div", {
91
+ className: "text-muted-foreground text-sm",
92
+ children: "No tenants available. Contact your administrator."
93
+ }) : /* @__PURE__ */ l(T, {
94
+ onValueChange: e.onChange,
95
+ value: e.value,
96
+ children: [/* @__PURE__ */ c(_, { children: /* @__PURE__ */ c(O, { children: /* @__PURE__ */ c(k, { placeholder: "Select a tenant" }) }) }), /* @__PURE__ */ c(E, { children: H.map((e) => /* @__PURE__ */ c(D, {
97
+ value: e.id,
98
+ children: e.name
99
+ }, e.id)) })]
100
+ }),
101
+ /* @__PURE__ */ c(v, { children: "Select which tenant this workspace belongs to" }),
102
+ /* @__PURE__ */ c(S, {})
103
+ ] })
104
+ }),
105
+ /* @__PURE__ */ c(y, {
106
+ control: W.control,
107
+ name: "organizationId",
108
+ render: ({ field: e }) => /* @__PURE__ */ l(b, { children: [
109
+ /* @__PURE__ */ c(x, { children: "Organization *" }),
110
+ B ? /* @__PURE__ */ c(g, { className: "h-10 w-full" }) : V ? /* @__PURE__ */ l("div", {
111
+ className: "flex items-center gap-2 text-destructive text-sm",
112
+ children: [/* @__PURE__ */ c(s, { size: 16 }), "Failed to load organizations"]
113
+ }) : G ? q.length === 0 ? /* @__PURE__ */ c("div", {
114
+ className: "text-muted-foreground text-sm",
115
+ children: "No organizations found for this tenant"
116
+ }) : /* @__PURE__ */ l(T, {
117
+ onValueChange: e.onChange,
118
+ value: e.value,
119
+ disabled: !G,
120
+ children: [/* @__PURE__ */ c(_, { children: /* @__PURE__ */ c(O, { children: /* @__PURE__ */ c(k, { placeholder: "Select an organization" }) }) }), /* @__PURE__ */ c(E, { children: q.map((e) => /* @__PURE__ */ c(D, {
121
+ value: e.id,
122
+ children: e.name
123
+ }, e.id)) })]
124
+ }) : /* @__PURE__ */ c("div", {
125
+ className: "text-muted-foreground text-sm",
126
+ children: "Please select a tenant first"
127
+ }),
128
+ /* @__PURE__ */ c(v, { children: "Select which organization owns this workspace" }),
129
+ /* @__PURE__ */ c(S, {})
130
+ ] })
131
+ }),
132
+ /* @__PURE__ */ c(y, {
133
+ control: W.control,
134
+ name: "type",
135
+ render: ({ field: e }) => /* @__PURE__ */ l(b, { children: [
136
+ /* @__PURE__ */ c(x, { children: "Workspace Type" }),
137
+ /* @__PURE__ */ l(T, {
138
+ onValueChange: e.onChange,
139
+ defaultValue: e.value,
140
+ children: [/* @__PURE__ */ c(_, { children: /* @__PURE__ */ c(O, { children: /* @__PURE__ */ c(k, { placeholder: "Select type" }) }) }), /* @__PURE__ */ l(E, { children: [/* @__PURE__ */ c(D, {
141
+ value: "TEAM",
142
+ children: "Team Workspace"
143
+ }), /* @__PURE__ */ c(D, {
144
+ value: "PERSONAL",
145
+ children: "Personal Workspace"
146
+ })] })]
147
+ }),
148
+ /* @__PURE__ */ c(v, { children: "Choose between a collaborative workspace or a personal one" }),
149
+ /* @__PURE__ */ c(S, {})
150
+ ] })
151
+ }),
152
+ /* @__PURE__ */ l(p, { children: [/* @__PURE__ */ c(u, {
153
+ type: "button",
154
+ variant: "outline",
155
+ onClick: N,
156
+ disabled: F,
157
+ children: "Cancel"
158
+ }), /* @__PURE__ */ c(u, {
159
+ type: "submit",
160
+ disabled: F || L || B,
161
+ children: F ? "Creating..." : "Create Workspace"
162
+ })] })
163
+ ]
164
+ })
165
+ })]
166
+ })
167
+ });
168
+ }
169
+ //#endregion
170
+ export { N as CreateWorkspaceDialog };
171
+
172
+ //# sourceMappingURL=CreateWorkspaceDialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CreateWorkspaceDialog.js","names":[],"sources":["../../src/components/CreateWorkspaceDialog.tsx"],"sourcesContent":["import { useEffect, useMemo } from 'react';\nimport { AlertCircle } from 'lucide-react';\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogFooter,\n Button,\n Skeleton,\n} from '@burdenoff/fe-libs/ui';\nimport {\n FormField,\n FormItem,\n FormLabel,\n FormControl,\n FormMessage,\n FormDescription,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n useForm,\n FormProvider,\n z,\n} from '@burdenoff/fe-libs/form';\nimport { useWorkspacesStore } from '../store/workspacesStore';\nimport { useCreateWorkspace } from '../hooks/useWorkspaceMutations';\nimport { useMyTenants, useMyOrganizations } from '../hooks/useTenants';\nimport { generateSlug } from '../utils/slug';\n\nconst createWorkspaceSchema = z.object({\n name: z.string().min(2, 'Name must be at least 2 characters').max(100),\n slug: z\n .string()\n .min(2, 'Slug must be at least 2 characters')\n .max(50)\n .regex(/^[a-z0-9-]+$/, 'Slug can only contain lowercase letters, numbers, and hyphens'),\n tenantId: z.string().min(1, 'Please select a tenant'),\n organizationId: z.string().min(1, 'Please select an organization'),\n type: z.enum(['TEAM', 'PERSONAL']).optional(),\n});\n\ntype CreateWorkspaceFormData = z.infer<typeof createWorkspaceSchema>;\n\nexport function CreateWorkspaceDialog() {\n const { isCreateWorkspaceDialogOpen, closeCreateWorkspaceDialog } = useWorkspacesStore();\n const { mutate: createWorkspace, isPending } = useCreateWorkspace();\n const { data: tenantsData, isLoading: isLoadingTenants, error: tenantsError } = useMyTenants();\n const {\n data: organizationsData,\n isLoading: isLoadingOrganizations,\n error: organizationsError,\n } = useMyOrganizations();\n\n const tenants = tenantsData?.items ?? [];\n const allOrganizations = organizationsData?.items ?? [];\n\n const form = useForm<CreateWorkspaceFormData>({\n schema: createWorkspaceSchema,\n defaultValues: {\n name: '',\n slug: '',\n tenantId: '',\n organizationId: '',\n type: 'TEAM',\n },\n });\n\n const selectedTenantId = form.watch('tenantId');\n const workspaceName = form.watch('name');\n\n // Filter organizations by selected tenant\n const filteredOrganizations = useMemo(() => {\n if (!selectedTenantId) return [];\n return allOrganizations.filter((org) => org.tenantId === selectedTenantId);\n }, [selectedTenantId, allOrganizations]);\n\n // Auto-generate slug from name (clear when name is empty)\n useEffect(() => {\n form.setValue('slug', workspaceName ? generateSlug(workspaceName) : '');\n }, [workspaceName, form]);\n\n // Reset organizationId when tenant changes\n useEffect(() => {\n form.setValue('organizationId', '');\n }, [selectedTenantId, form]);\n\n const onSubmit = (data: CreateWorkspaceFormData) => {\n createWorkspace(\n {\n name: data.name,\n slug: data.slug,\n tenantId: data.tenantId,\n organizationId: data.organizationId,\n type: data.type,\n },\n {\n onSuccess: () => {\n closeCreateWorkspaceDialog();\n form.reset();\n },\n }\n );\n };\n\n return (\n <Dialog open={isCreateWorkspaceDialogOpen} onOpenChange={closeCreateWorkspaceDialog}>\n <DialogContent className=\"sm:max-w-[500px]\">\n <DialogHeader>\n <DialogTitle>Create Workspace</DialogTitle>\n </DialogHeader>\n\n <FormProvider {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-4\">\n {/* Workspace Name */}\n <FormField\n control={form.control}\n name=\"name\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Workspace Name *</FormLabel>\n <FormControl>\n <Input placeholder=\"My Workspace\" {...field} />\n </FormControl>\n <FormDescription>A descriptive name for your workspace</FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n {/* Slug */}\n <FormField\n control={form.control}\n name=\"slug\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Slug *</FormLabel>\n <FormControl>\n <Input placeholder=\"my-workspace\" {...field} />\n </FormControl>\n <FormDescription>URL-friendly identifier (auto-generated)</FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n {/* Tenant Selection */}\n <FormField\n control={form.control}\n name=\"tenantId\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Tenant *</FormLabel>\n {isLoadingTenants ? (\n <Skeleton className=\"h-10 w-full\" />\n ) : tenantsError ? (\n <div className=\"flex items-center gap-2 text-destructive text-sm\">\n <AlertCircle size={16} />\n Failed to load tenants\n </div>\n ) : tenants.length === 0 ? (\n <div className=\"text-muted-foreground text-sm\">\n No tenants available. Contact your administrator.\n </div>\n ) : (\n <Select onValueChange={field.onChange} value={field.value}>\n <FormControl>\n <SelectTrigger>\n <SelectValue placeholder=\"Select a tenant\" />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n {tenants.map((tenant) => (\n <SelectItem key={tenant.id} value={tenant.id}>\n {tenant.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n <FormDescription>Select which tenant this workspace belongs to</FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n {/* Organization Selection */}\n <FormField\n control={form.control}\n name=\"organizationId\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Organization *</FormLabel>\n {isLoadingOrganizations ? (\n <Skeleton className=\"h-10 w-full\" />\n ) : organizationsError ? (\n <div className=\"flex items-center gap-2 text-destructive text-sm\">\n <AlertCircle size={16} />\n Failed to load organizations\n </div>\n ) : !selectedTenantId ? (\n <div className=\"text-muted-foreground text-sm\">\n Please select a tenant first\n </div>\n ) : filteredOrganizations.length === 0 ? (\n <div className=\"text-muted-foreground text-sm\">\n No organizations found for this tenant\n </div>\n ) : (\n <Select\n onValueChange={field.onChange}\n value={field.value}\n disabled={!selectedTenantId}\n >\n <FormControl>\n <SelectTrigger>\n <SelectValue placeholder=\"Select an organization\" />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n {filteredOrganizations.map((org) => (\n <SelectItem key={org.id} value={org.id}>\n {org.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n <FormDescription>Select which organization owns this workspace</FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n {/* Workspace Type */}\n <FormField\n control={form.control}\n name=\"type\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Workspace Type</FormLabel>\n <Select onValueChange={field.onChange} defaultValue={field.value}>\n <FormControl>\n <SelectTrigger>\n <SelectValue placeholder=\"Select type\" />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n <SelectItem value=\"TEAM\">Team Workspace</SelectItem>\n <SelectItem value=\"PERSONAL\">Personal Workspace</SelectItem>\n </SelectContent>\n </Select>\n <FormDescription>\n Choose between a collaborative workspace or a personal one\n </FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={closeCreateWorkspaceDialog}\n disabled={isPending}\n >\n Cancel\n </Button>\n <Button\n type=\"submit\"\n disabled={isPending || isLoadingTenants || isLoadingOrganizations}\n >\n {isPending ? 'Creating...' : 'Create Workspace'}\n </Button>\n </DialogFooter>\n </form>\n </FormProvider>\n </DialogContent>\n </Dialog>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ interface InviteMemberDialogProps {
2
+ /** Workspace ID to invite the member to (from URL params) */
3
+ workspaceId?: string;
4
+ }
5
+ export declare function InviteMemberDialog({ workspaceId }: InviteMemberDialogProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
7
+ //# sourceMappingURL=InviteMemberDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InviteMemberDialog.d.ts","sourceRoot":"","sources":["../../src/components/InviteMemberDialog.tsx"],"names":[],"mappings":"AAoCA,UAAU,uBAAuB;IAC/B,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,WAAW,EAAE,EAAE,uBAAuB,2CAkL1E"}
@@ -0,0 +1,148 @@
1
+ import { useWorkspacesStore as e } from "../store/workspacesStore.js";
2
+ import { useCreateInvitation as t } from "../hooks/useMemberMutations.js";
3
+ import { useWorkspaceRoles as n } from "../hooks/useWorkspaceRoles.js";
4
+ import { useState as r } from "react";
5
+ import { AlertCircle as i } from "lucide-react";
6
+ import { jsx as a, jsxs as o } from "react/jsx-runtime";
7
+ import { Badge as s, Button as c, Dialog as l, DialogContent as u, DialogDescription as d, DialogHeader as f, DialogTitle as p } from "@burdenoff/fe-libs/ui";
8
+ import { FormControl as m, FormDescription as h, FormField as g, FormItem as _, FormLabel as v, FormMessage as y, FormProvider as b, Input as x, useForm as S, z as C } from "@burdenoff/fe-libs/form";
9
+ //#region src/components/InviteMemberDialog.tsx
10
+ var w = C.object({
11
+ email: C.string().email("Invalid email address"),
12
+ roleIds: C.array(C.string())
13
+ });
14
+ function T({ workspaceId: C }) {
15
+ let { isInviteMemberDialogOpen: T, closeInviteMemberDialog: E } = e(), { mutate: D, isPending: O } = t(C), { data: k = [], isLoading: A } = n(C), [j, M] = r(null), N = S({
16
+ schema: w,
17
+ defaultValues: {
18
+ email: "",
19
+ roleIds: []
20
+ }
21
+ }), P = (e) => {
22
+ if (M(null), !C) {
23
+ M("No workspace selected. Please select a workspace first.");
24
+ return;
25
+ }
26
+ D({
27
+ email: e.email,
28
+ roleIds: e.roleIds,
29
+ workspaceId: C
30
+ }, {
31
+ onSuccess: () => {
32
+ E(), N.reset(), M(null);
33
+ },
34
+ onError: (e) => {
35
+ let t = e instanceof Error ? e.message : "Failed to send invitation";
36
+ console.error("Failed to create invitation:", e), M(t);
37
+ }
38
+ });
39
+ }, F = (e) => {
40
+ e || (E(), N.reset(), M(null));
41
+ };
42
+ return /* @__PURE__ */ a(l, {
43
+ open: T,
44
+ onOpenChange: F,
45
+ children: /* @__PURE__ */ o(u, {
46
+ className: "sm:max-w-[500px]",
47
+ children: [/* @__PURE__ */ o(f, { children: [/* @__PURE__ */ a(p, { children: "Invite Member" }), /* @__PURE__ */ a(d, { children: "Invite a new member to this workspace by email. They'll receive an invitation link to join." })] }), /* @__PURE__ */ a(b, {
48
+ ...N,
49
+ children: /* @__PURE__ */ o("form", {
50
+ onSubmit: N.handleSubmit(P),
51
+ className: "space-y-4",
52
+ children: [
53
+ j && /* @__PURE__ */ o("div", {
54
+ className: "flex items-center gap-2 p-3 text-sm text-destructive bg-destructive/10 border border-destructive/20 rounded-md",
55
+ children: [/* @__PURE__ */ a(i, { className: "h-4 w-4 flex-shrink-0" }), /* @__PURE__ */ a("span", { children: j })]
56
+ }),
57
+ /* @__PURE__ */ a(g, {
58
+ control: N.control,
59
+ name: "email",
60
+ render: ({ field: e }) => /* @__PURE__ */ o(_, { children: [
61
+ /* @__PURE__ */ a(v, { children: "Email Address *" }),
62
+ /* @__PURE__ */ a(m, { children: /* @__PURE__ */ a(x, {
63
+ type: "email",
64
+ placeholder: "member@example.com",
65
+ ...e,
66
+ disabled: O,
67
+ onChange: (t) => {
68
+ e.onChange(t), M(null);
69
+ }
70
+ }) }),
71
+ /* @__PURE__ */ a(h, { children: "Enter the email address of the person you want to invite" }),
72
+ /* @__PURE__ */ a(y, {})
73
+ ] })
74
+ }),
75
+ /* @__PURE__ */ a(g, {
76
+ control: N.control,
77
+ name: "roleIds",
78
+ render: ({ field: e }) => /* @__PURE__ */ o(_, { children: [
79
+ /* @__PURE__ */ o("div", {
80
+ className: "flex items-center justify-between gap-2",
81
+ children: [/* @__PURE__ */ a(v, { children: "Roles (Optional)" }), e.value.length > 0 && /* @__PURE__ */ o(s, {
82
+ variant: "secondary",
83
+ children: [e.value.length, " selected"]
84
+ })]
85
+ }),
86
+ /* @__PURE__ */ a(m, { children: /* @__PURE__ */ a("div", {
87
+ className: "grid grid-cols-1 gap-2 sm:grid-cols-2",
88
+ children: A ? /* @__PURE__ */ a("p", {
89
+ className: "text-sm text-muted-foreground",
90
+ children: "Loading roles…"
91
+ }) : k.length === 0 ? /* @__PURE__ */ a("p", {
92
+ className: "text-sm text-muted-foreground",
93
+ children: "No assignable roles were returned for this workspace."
94
+ }) : k.map((t) => {
95
+ let n = e.value.includes(t.id);
96
+ return /* @__PURE__ */ o("button", {
97
+ type: "button",
98
+ "aria-pressed": n,
99
+ disabled: O,
100
+ onClick: () => {
101
+ let r = n ? e.value.filter((e) => e !== t.id) : [...e.value, t.id];
102
+ e.onChange(r);
103
+ },
104
+ className: `rounded-md border p-3 text-left transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ${n ? "border-primary bg-primary/10 text-foreground" : "border-border bg-background text-foreground hover:bg-accent"}`,
105
+ children: [/* @__PURE__ */ o("div", {
106
+ className: "flex items-center justify-between gap-2",
107
+ children: [/* @__PURE__ */ a("span", {
108
+ className: "font-medium",
109
+ children: t.name
110
+ }), t.isSystem && /* @__PURE__ */ a(s, {
111
+ variant: "outline",
112
+ children: "System"
113
+ })]
114
+ }), t.description && /* @__PURE__ */ a("p", {
115
+ className: "mt-1 text-xs text-muted-foreground",
116
+ children: t.description
117
+ })]
118
+ }, t.id);
119
+ })
120
+ }) }),
121
+ /* @__PURE__ */ a(h, { children: "Choose the roles to assign once the invitation is accepted." }),
122
+ /* @__PURE__ */ a(y, {})
123
+ ] })
124
+ }),
125
+ /* @__PURE__ */ o("div", {
126
+ className: "flex justify-end gap-3 pt-4",
127
+ children: [/* @__PURE__ */ a(c, {
128
+ type: "button",
129
+ variant: "outline",
130
+ onClick: () => F(!1),
131
+ disabled: O,
132
+ children: "Cancel"
133
+ }), /* @__PURE__ */ a(c, {
134
+ type: "submit",
135
+ disabled: O,
136
+ children: O ? "Sending..." : "Send Invitation"
137
+ })]
138
+ })
139
+ ]
140
+ })
141
+ })]
142
+ })
143
+ });
144
+ }
145
+ //#endregion
146
+ export { T as InviteMemberDialog };
147
+
148
+ //# sourceMappingURL=InviteMemberDialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InviteMemberDialog.js","names":[],"sources":["../../src/components/InviteMemberDialog.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { AlertCircle } from 'lucide-react';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n Button,\n Badge,\n} from '@burdenoff/fe-libs/ui';\nimport {\n FormField,\n FormItem,\n FormLabel,\n FormControl,\n FormMessage,\n FormDescription,\n Input,\n useForm,\n FormProvider,\n z,\n} from '@burdenoff/fe-libs/form';\nimport { useWorkspacesStore } from '../store/workspacesStore';\nimport { useCreateInvitation } from '../hooks/useMemberMutations';\nimport { useWorkspaceRoles } from '../hooks/useWorkspaceRoles';\n\nconst inviteMemberSchema = z.object({\n email: z.string().email('Invalid email address'),\n // Using a lambda default instead of `.default([])` to keep input type required\n // (zod v4 widens defaulted inputs to `T | undefined`, which breaks useForm typing).\n roleIds: z.array(z.string()),\n});\n\ntype InviteMemberFormData = z.infer<typeof inviteMemberSchema>;\n\ninterface InviteMemberDialogProps {\n /** Workspace ID to invite the member to (from URL params) */\n workspaceId?: string;\n}\n\nexport function InviteMemberDialog({ workspaceId }: InviteMemberDialogProps) {\n const { isInviteMemberDialogOpen, closeInviteMemberDialog } = useWorkspacesStore();\n const { mutate: createInvitation, isPending } = useCreateInvitation(workspaceId);\n const { data: availableRoles = [], isLoading: isLoadingRoles } = useWorkspaceRoles(workspaceId);\n const [error, setError] = useState<string | null>(null);\n\n const form = useForm<InviteMemberFormData>({\n schema: inviteMemberSchema,\n defaultValues: {\n email: '',\n roleIds: [],\n },\n });\n\n const onSubmit = (data: InviteMemberFormData) => {\n setError(null);\n\n if (!workspaceId) {\n setError('No workspace selected. Please select a workspace first.');\n return;\n }\n\n createInvitation(\n {\n email: data.email,\n roleIds: data.roleIds,\n workspaceId,\n },\n {\n onSuccess: () => {\n closeInviteMemberDialog();\n form.reset();\n setError(null);\n },\n onError: (err) => {\n const errorMessage = err instanceof Error ? err.message : 'Failed to send invitation';\n console.error('Failed to create invitation:', err);\n setError(errorMessage);\n },\n }\n );\n };\n\n const handleOpenChange = (open: boolean) => {\n if (!open) {\n closeInviteMemberDialog();\n form.reset();\n setError(null);\n }\n };\n\n return (\n <Dialog open={isInviteMemberDialogOpen} onOpenChange={handleOpenChange}>\n <DialogContent className=\"sm:max-w-[500px]\">\n <DialogHeader>\n <DialogTitle>Invite Member</DialogTitle>\n <DialogDescription>\n Invite a new member to this workspace by email. They'll receive an invitation link to\n join.\n </DialogDescription>\n </DialogHeader>\n\n <FormProvider {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-4\">\n {error && (\n <div className=\"flex items-center gap-2 p-3 text-sm text-destructive bg-destructive/10 border border-destructive/20 rounded-md\">\n <AlertCircle className=\"h-4 w-4 flex-shrink-0\" />\n <span>{error}</span>\n </div>\n )}\n\n <FormField\n control={form.control}\n name=\"email\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Email Address *</FormLabel>\n <FormControl>\n <Input\n type=\"email\"\n placeholder=\"member@example.com\"\n {...field}\n disabled={isPending}\n onChange={(e) => {\n field.onChange(e);\n setError(null); // Clear error when user types\n }}\n />\n </FormControl>\n <FormDescription>\n Enter the email address of the person you want to invite\n </FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"roleIds\"\n render={({ field }) => (\n <FormItem>\n <div className=\"flex items-center justify-between gap-2\">\n <FormLabel>Roles (Optional)</FormLabel>\n {field.value.length > 0 && (\n <Badge variant=\"secondary\">{field.value.length} selected</Badge>\n )}\n </div>\n <FormControl>\n <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n {isLoadingRoles ? (\n <p className=\"text-sm text-muted-foreground\">Loading roles…</p>\n ) : availableRoles.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">\n No assignable roles were returned for this workspace.\n </p>\n ) : (\n availableRoles.map((role) => {\n const isSelected = field.value.includes(role.id);\n return (\n <button\n key={role.id}\n type=\"button\"\n aria-pressed={isSelected}\n disabled={isPending}\n onClick={() => {\n const nextValue = isSelected\n ? field.value.filter((id) => id !== role.id)\n : [...field.value, role.id];\n field.onChange(nextValue);\n }}\n className={`rounded-md border p-3 text-left transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ${\n isSelected\n ? 'border-primary bg-primary/10 text-foreground'\n : 'border-border bg-background text-foreground hover:bg-accent'\n }`}\n >\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"font-medium\">{role.name}</span>\n {role.isSystem && <Badge variant=\"outline\">System</Badge>}\n </div>\n {role.description && (\n <p className=\"mt-1 text-xs text-muted-foreground\">\n {role.description}\n </p>\n )}\n </button>\n );\n })\n )}\n </div>\n </FormControl>\n <FormDescription>\n Choose the roles to assign once the invitation is accepted.\n </FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <div className=\"flex justify-end gap-3 pt-4\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => handleOpenChange(false)}\n disabled={isPending}\n >\n Cancel\n </Button>\n <Button type=\"submit\" disabled={isPending}>\n {isPending ? 'Sending...' : 'Send Invitation'}\n </Button>\n </div>\n </form>\n </FormProvider>\n </DialogContent>\n </Dialog>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { WorkspaceMember } from '../types';
2
+
3
+ export interface MemberListItemProps {
4
+ member: WorkspaceMember;
5
+ onUpdateRoles?: (memberId: string, roleIds: string[]) => void;
6
+ selected?: boolean;
7
+ onToggleSelect?: (checked: boolean) => void;
8
+ canRemove?: boolean;
9
+ }
10
+ export declare function MemberListItem({ member, selected, onToggleSelect, canRemove, }: MemberListItemProps): import("react/jsx-runtime").JSX.Element;
11
+ //# sourceMappingURL=MemberListItem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemberListItem.d.ts","sourceRoot":"","sources":["../../src/components/MemberListItem.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAmBhD,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,eAAe,CAAC;IACxB,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC9D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,QAAgB,EAChB,cAAc,EACd,SAAiB,GAClB,EAAE,mBAAmB,2CAwHrB"}
@@ -0,0 +1,118 @@
1
+ import { nativeImpact as e, nativeNotify as t } from "../utils/nativeBridge.js";
2
+ import { useRemoveWorkspaceMember as n } from "../hooks/useMemberMutations.js";
3
+ import { formatRelativeTime as r } from "../utils/formatters.js";
4
+ import { useState as i } from "react";
5
+ import { MoreHorizontal as a, UserMinus as o } from "lucide-react";
6
+ import { Fragment as s, jsx as c, jsxs as l } from "react/jsx-runtime";
7
+ import { AlertDialog as u, AlertDialogAction as d, AlertDialogCancel as f, AlertDialogContent as p, AlertDialogDescription as m, AlertDialogFooter as h, AlertDialogHeader as g, AlertDialogTitle as _, Badge as v, Button as y, Card as b, CardContent as x, DropdownMenu as S, DropdownMenuContent as C, DropdownMenuTrigger as w } from "@burdenoff/fe-libs/ui";
8
+ //#region src/components/MemberListItem.tsx
9
+ function T(e, t) {
10
+ for (let n of t) {
11
+ let t = e?.[n];
12
+ if (typeof t == "string" && t.trim()) return t;
13
+ }
14
+ return null;
15
+ }
16
+ function E(e) {
17
+ return e.split(/\s+|@/).map((e) => e.trim()).filter(Boolean).slice(0, 2).map((e) => e[0]?.toUpperCase() ?? "").join("") || "U";
18
+ }
19
+ function D({ member: D, selected: O = !1, onToggleSelect: k, canRemove: A = !1 }) {
20
+ let [j, M] = i(!1), { mutate: N, isPending: P } = n(D.workspaceId), F = D.context?.metadata, I = T(F, [
21
+ "displayName",
22
+ "name",
23
+ "email"
24
+ ]) ?? `User ${D.userId}`, L = T(F, ["avatarUrl", "avatar"]);
25
+ return /* @__PURE__ */ l(s, { children: [/* @__PURE__ */ c(b, {
26
+ className: `hover:bg-accent/5 transition-all duration-200 ${O ? "ring-2 ring-primary/25 border-primary/50" : ""}`,
27
+ children: /* @__PURE__ */ c(x, {
28
+ className: "p-4",
29
+ children: /* @__PURE__ */ l("div", {
30
+ className: "flex items-center justify-between gap-4",
31
+ children: [/* @__PURE__ */ l("div", {
32
+ className: "flex items-center gap-3 flex-1 min-w-0",
33
+ children: [
34
+ k && /* @__PURE__ */ c("input", {
35
+ type: "checkbox",
36
+ checked: O,
37
+ onChange: (e) => k(e.target.checked),
38
+ className: "h-4 w-4 rounded border-border text-primary",
39
+ "aria-label": `Select member ${D.userId}`
40
+ }),
41
+ /* @__PURE__ */ c("div", {
42
+ className: "w-10 h-10 rounded-full bg-primary/10 flex items-center justify-center flex-shrink-0 transition-colors",
43
+ children: L ? /* @__PURE__ */ c("img", {
44
+ src: L,
45
+ alt: I,
46
+ className: "h-full w-full rounded-full object-cover"
47
+ }) : /* @__PURE__ */ c("span", {
48
+ className: "text-sm font-semibold text-primary",
49
+ children: E(I)
50
+ })
51
+ }),
52
+ /* @__PURE__ */ l("div", {
53
+ className: "flex-1 min-w-0",
54
+ children: [/* @__PURE__ */ l("div", {
55
+ className: "flex items-center gap-2",
56
+ children: [/* @__PURE__ */ c("p", {
57
+ className: "font-medium text-sm text-primary truncate",
58
+ children: I
59
+ }), /* @__PURE__ */ c(v, {
60
+ variant: "secondary",
61
+ className: "text-xs",
62
+ children: "Workspace member"
63
+ })]
64
+ }), /* @__PURE__ */ l("p", {
65
+ className: "text-xs text-muted-foreground",
66
+ children: ["Joined ", r(D.createdAt)]
67
+ })]
68
+ })
69
+ ]
70
+ }), A && /* @__PURE__ */ l(S, { children: [/* @__PURE__ */ c(w, {
71
+ asChild: !0,
72
+ children: /* @__PURE__ */ l(y, {
73
+ variant: "ghost",
74
+ size: "icon",
75
+ className: "h-8 w-8 flex-shrink-0",
76
+ children: [/* @__PURE__ */ c(a, { className: "h-4 w-4" }), /* @__PURE__ */ c("span", {
77
+ className: "sr-only",
78
+ children: "Open member actions"
79
+ })]
80
+ })
81
+ }), /* @__PURE__ */ c(C, {
82
+ align: "end",
83
+ children: /* @__PURE__ */ l("button", {
84
+ type: "button",
85
+ onClick: () => M(!0),
86
+ className: "flex w-full items-center rounded-sm px-2 py-1.5 text-sm text-destructive outline-none transition-colors hover:bg-accent hover:text-destructive focus:bg-accent focus:text-destructive",
87
+ children: [/* @__PURE__ */ c(o, { className: "mr-2 h-4 w-4" }), "Remove Member"]
88
+ })
89
+ })] })]
90
+ })
91
+ })
92
+ }), /* @__PURE__ */ c(u, {
93
+ open: j,
94
+ onOpenChange: M,
95
+ children: /* @__PURE__ */ l(p, { children: [/* @__PURE__ */ l(g, { children: [/* @__PURE__ */ c(_, { children: "Remove Member" }), /* @__PURE__ */ c(m, { children: "Are you sure you want to remove this member from the workspace? This action cannot be undone." })] }), /* @__PURE__ */ l(h, { children: [/* @__PURE__ */ c(f, {
96
+ disabled: P,
97
+ children: "Cancel"
98
+ }), /* @__PURE__ */ c(d, {
99
+ onClick: () => {
100
+ e("medium"), N(D.id, {
101
+ onSuccess: () => {
102
+ t("success"), M(!1);
103
+ },
104
+ onError: () => {
105
+ t("error");
106
+ }
107
+ });
108
+ },
109
+ disabled: P,
110
+ className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
111
+ children: P ? "Removing..." : "Remove Member"
112
+ })] })] })
113
+ })] });
114
+ }
115
+ //#endregion
116
+ export { D as MemberListItem };
117
+
118
+ //# sourceMappingURL=MemberListItem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemberListItem.js","names":[],"sources":["../../src/components/MemberListItem.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n Card,\n CardContent,\n Button,\n Badge,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuTrigger,\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from '@burdenoff/fe-libs/ui';\nimport { MoreHorizontal, UserMinus } from 'lucide-react';\nimport { useRemoveWorkspaceMember } from '../hooks/useMemberMutations';\nimport { nativeImpact, nativeNotify } from '../utils/nativeBridge';\nimport { formatRelativeTime } from '../utils/formatters';\nimport type { WorkspaceMember } from '../types';\n\nfunction getMetadataString(metadata: Record<string, unknown> | undefined, keys: string[]) {\n for (const key of keys) {\n const value = metadata?.[key];\n if (typeof value === 'string' && value.trim()) return value;\n }\n return null;\n}\n\nfunction getInitials(value: string) {\n const parts = value\n .split(/\\s+|@/)\n .map((part) => part.trim())\n .filter(Boolean);\n const initials = parts.slice(0, 2).map((part) => part[0]?.toUpperCase() ?? '');\n return initials.join('') || 'U';\n}\n\nexport interface MemberListItemProps {\n member: WorkspaceMember;\n onUpdateRoles?: (memberId: string, roleIds: string[]) => void;\n selected?: boolean;\n onToggleSelect?: (checked: boolean) => void;\n canRemove?: boolean;\n}\n\nexport function MemberListItem({\n member,\n selected = false,\n onToggleSelect,\n canRemove = false,\n}: MemberListItemProps) {\n const [showRemoveDialog, setShowRemoveDialog] = useState(false);\n const { mutate: removeMember, isPending: isRemoving } = useRemoveWorkspaceMember(\n member.workspaceId\n );\n const metadata = member.context?.metadata;\n const displayName =\n getMetadataString(metadata, ['displayName', 'name', 'email']) ?? `User ${member.userId}`;\n const avatarUrl = getMetadataString(metadata, ['avatarUrl', 'avatar']);\n\n const handleRemove = () => {\n void nativeImpact('medium');\n removeMember(member.id, {\n onSuccess: () => {\n void nativeNotify('success');\n setShowRemoveDialog(false);\n },\n onError: () => {\n void nativeNotify('error');\n },\n });\n };\n\n return (\n <>\n <Card\n className={`hover:bg-accent/5 transition-all duration-200 ${\n selected ? 'ring-2 ring-primary/25 border-primary/50' : ''\n }`}\n >\n <CardContent className=\"p-4\">\n <div className=\"flex items-center justify-between gap-4\">\n {/* Member Info */}\n <div className=\"flex items-center gap-3 flex-1 min-w-0\">\n {onToggleSelect && (\n <input\n type=\"checkbox\"\n checked={selected}\n onChange={(event) => onToggleSelect(event.target.checked)}\n className=\"h-4 w-4 rounded border-border text-primary\"\n aria-label={`Select member ${member.userId}`}\n />\n )}\n <div className=\"w-10 h-10 rounded-full bg-primary/10 flex items-center justify-center flex-shrink-0 transition-colors\">\n {avatarUrl ? (\n <img\n src={avatarUrl}\n alt={displayName}\n className=\"h-full w-full rounded-full object-cover\"\n />\n ) : (\n <span className=\"text-sm font-semibold text-primary\">\n {getInitials(displayName)}\n </span>\n )}\n </div>\n\n {/* Member Details */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <p className=\"font-medium text-sm text-primary truncate\">{displayName}</p>\n <Badge variant=\"secondary\" className=\"text-xs\">\n Workspace member\n </Badge>\n </div>\n <p className=\"text-xs text-muted-foreground\">\n Joined {formatRelativeTime(member.createdAt)}\n </p>\n </div>\n </div>\n\n {/* Actions */}\n {canRemove && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-8 w-8 flex-shrink-0\">\n <MoreHorizontal className=\"h-4 w-4\" />\n <span className=\"sr-only\">Open member actions</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <button\n type=\"button\"\n onClick={() => setShowRemoveDialog(true)}\n className=\"flex w-full items-center rounded-sm px-2 py-1.5 text-sm text-destructive outline-none transition-colors hover:bg-accent hover:text-destructive focus:bg-accent focus:text-destructive\"\n >\n <UserMinus className=\"mr-2 h-4 w-4\" />\n Remove Member\n </button>\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </div>\n </CardContent>\n </Card>\n\n {/* Remove Confirmation Dialog */}\n <AlertDialog open={showRemoveDialog} onOpenChange={setShowRemoveDialog}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Remove Member</AlertDialogTitle>\n <AlertDialogDescription>\n Are you sure you want to remove this member from the workspace? This action cannot be\n undone.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={isRemoving}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={handleRemove}\n disabled={isRemoving}\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n >\n {isRemoving ? 'Removing...' : 'Remove Member'}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { Project, ProjectTag } from '../types';
2
+
3
+ interface ProjectCardProps {
4
+ project: Project;
5
+ selected?: boolean;
6
+ onToggleSelect?: (checked: boolean) => void;
7
+ onTagClick?: (tag: ProjectTag) => void;
8
+ canArchive?: boolean;
9
+ canDelete?: boolean;
10
+ }
11
+ export declare function ProjectCard({ project, selected, onToggleSelect, onTagClick, canArchive, canDelete, }: ProjectCardProps): import("react/jsx-runtime").JSX.Element;
12
+ export {};
13
+ //# sourceMappingURL=ProjectCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProjectCard.d.ts","sourceRoot":"","sources":["../../src/components/ProjectCard.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAapD,UAAU,gBAAgB;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,CAAC;IACvC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,QAAgB,EAChB,cAAc,EACd,UAAU,EACV,UAAkB,EAClB,SAAiB,GAClB,EAAE,gBAAgB,2CA4JlB"}