@burdenoff/microfe-workspaces 2026.802.1 → 2026.829.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 (55) hide show
  1. package/dist/generated/global-operations.js +44 -1
  2. package/dist/generated/global-operations.js.map +1 -1
  3. package/dist/generated/wspace-operations.js +18 -18
  4. package/dist/generated/wspace-operations.js.map +1 -1
  5. package/dist/hooks/useWorkspaceMutations.js +84 -61
  6. package/dist/hooks/useWorkspaceMutations.js.map +1 -1
  7. package/dist/pages/MembersListPage.js +3 -3
  8. package/dist/pages/MembersListPage.js.map +1 -1
  9. package/dist/pages/ProjectsListPage.js +3 -3
  10. package/dist/pages/ProjectsListPage.js.map +1 -1
  11. package/dist/pages/WorkspaceDetailPage.js +152 -114
  12. package/dist/pages/WorkspaceDetailPage.js.map +1 -1
  13. package/dist/pages/WorkspaceInvitePage.js +2 -2
  14. package/dist/pages/WorkspaceInvitePage.js.map +1 -1
  15. package/dist/pages/dashboard/DashboardCustomizer.js +62 -62
  16. package/dist/pages/dashboard/DashboardCustomizer.js.map +1 -1
  17. package/dist/pages/dashboard/DashboardPage.js +88 -69
  18. package/dist/pages/dashboard/DashboardPage.js.map +1 -1
  19. package/dist/pages/dashboard/config.js +77 -1
  20. package/dist/pages/dashboard/config.js.map +1 -1
  21. package/dist/pages/dashboard/widgets/AgentsWidget.js +56 -54
  22. package/dist/pages/dashboard/widgets/AgentsWidget.js.map +1 -1
  23. package/dist/pages/dashboard/widgets/GroupsWidget.js +29 -31
  24. package/dist/pages/dashboard/widgets/GroupsWidget.js.map +1 -1
  25. package/dist/pages/dashboard/widgets/MembersWidget.js +33 -33
  26. package/dist/pages/dashboard/widgets/MembersWidget.js.map +1 -1
  27. package/dist/pages/dashboard/widgets/ProjectsWidget.js +42 -44
  28. package/dist/pages/dashboard/widgets/ProjectsWidget.js.map +1 -1
  29. package/dist/pages/dashboard/widgets/QuickActionsWidget.js +171 -161
  30. package/dist/pages/dashboard/widgets/QuickActionsWidget.js.map +1 -1
  31. package/dist/pages/dashboard/widgets/RecentActivityWidget.js +54 -44
  32. package/dist/pages/dashboard/widgets/RecentActivityWidget.js.map +1 -1
  33. package/dist/pages/dashboard/widgets/SessionsWidget.js +57 -41
  34. package/dist/pages/dashboard/widgets/SessionsWidget.js.map +1 -1
  35. package/dist/pages/dashboard/widgets/StorageWidget.js +52 -54
  36. package/dist/pages/dashboard/widgets/StorageWidget.js.map +1 -1
  37. package/dist/pages/dashboard/widgets/TagCloudWidget.js +28 -30
  38. package/dist/pages/dashboard/widgets/TagCloudWidget.js.map +1 -1
  39. package/dist/pages/dashboard/widgets/TipsWidget.js +141 -131
  40. package/dist/pages/dashboard/widgets/TipsWidget.js.map +1 -1
  41. package/dist/pages/dashboard/widgets/UpcomingEventsWidget.js +46 -40
  42. package/dist/pages/dashboard/widgets/UpcomingEventsWidget.js.map +1 -1
  43. package/dist/pages/dashboard/widgets/VibesWidget.js +44 -34
  44. package/dist/pages/dashboard/widgets/VibesWidget.js.map +1 -1
  45. package/dist/pages/dashboard/widgets/WelcomeWidget.js +43 -41
  46. package/dist/pages/dashboard/widgets/WelcomeWidget.js.map +1 -1
  47. package/dist/pages/dashboard/widgets/WorkflowRunsWidget.js +68 -62
  48. package/dist/pages/dashboard/widgets/WorkflowRunsWidget.js.map +1 -1
  49. package/dist/pages/dashboard/widgets/WorkflowStatsWidget.js +50 -44
  50. package/dist/pages/dashboard/widgets/WorkflowStatsWidget.js.map +1 -1
  51. package/dist/pages/dashboard/widgets/WorkflowsOverviewWidget.js +59 -49
  52. package/dist/pages/dashboard/widgets/WorkflowsOverviewWidget.js.map +1 -1
  53. package/dist/pages/dashboard/widgets/WorkspacesWidget.js +35 -33
  54. package/dist/pages/dashboard/widgets/WorkspacesWidget.js.map +1 -1
  55. package/package.json +4 -4
@@ -2,74 +2,85 @@ import { useWorkspacesContext as e } from "../providers/WorkspacesProvider.js";
2
2
  import { useWorkspace as t } from "../hooks/useWorkspaces.js";
3
3
  import { useScopedNavigation as n } from "../hooks/useScopedNavigation.js";
4
4
  import { tWithFallback as r } from "../utils/i18n.js";
5
- import { useWorkspacesPageView as i } from "../hooks/useWorkspacesPageView.js";
6
- import { useWorkspaceMembers as a } from "../hooks/useWorkspaceMembers.js";
7
- import { useWorkspacePermissions as o } from "../hooks/useWorkspacePermissions.js";
8
- import { useProjects as s } from "../hooks/useProjects.js";
9
- import { useWorkspaceActivity as c } from "../hooks/useWorkspaceActivity.js";
10
- import { Activity as l, ArrowLeft as u, ChevronRight as d, FolderKanban as f, Settings as p, UserPlus as m, Users as h } from "lucide-react";
5
+ import { useWorkspacesPageView as ee } from "../hooks/useWorkspacesPageView.js";
6
+ import { useWorkspaceMembers as te } from "../hooks/useWorkspaceMembers.js";
7
+ import { useWorkspacePermissions as ne } from "../hooks/useWorkspacePermissions.js";
8
+ import { useProjects as i } from "../hooks/useProjects.js";
9
+ import { useArchiveWorkspace as a } from "../hooks/useWorkspaceMutations.js";
10
+ import { useWorkspaceActivity as o } from "../hooks/useWorkspaceActivity.js";
11
+ import { useState as s } from "react";
12
+ import { Activity as c, Archive as l, ArrowLeft as u, ChevronRight as d, FolderKanban as f, Settings as p, UserPlus as m, Users as h } from "lucide-react";
11
13
  import { Fragment as g, jsx as _, jsxs as v } from "react/jsx-runtime";
12
- import { Badge as y, Button as b, CTAOverflowMenu as x, CardContent as S, CardHeader as C, CardTitle as w, GlassCard as T, IllustratedEmptyState as E, NextSteps as D, PagePurpose as O, Skeleton as k } from "@burdenoff/fe-libs/ui";
13
- import { useNavigate as A, useParams as j } from "react-router";
14
- import { useI18n as M } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
14
+ import { AlertDialog as y, AlertDialogAction as b, AlertDialogCancel as x, AlertDialogContent as S, AlertDialogDescription as re, AlertDialogFooter as C, AlertDialogHeader as w, AlertDialogTitle as T, Badge as E, Button as D, CTAOverflowMenu as ie, CardContent as O, CardHeader as k, CardTitle as A, GlassCard as j, IllustratedEmptyState as M, NextSteps as N, PagePurpose as P, Skeleton as F } from "@burdenoff/fe-libs/ui";
15
+ import { useNavigate as I, useParams as L } from "react-router";
16
+ import { useI18n as R } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
15
17
  //#region src/pages/WorkspaceDetailPage.tsx
16
- function N() {
17
- let { workspaceId: N } = j();
18
- i("workspaces.detail", {
19
- workspaceId: N,
18
+ function z() {
19
+ let { workspaceId: z } = L();
20
+ ee("workspaces.detail", {
21
+ workspaceId: z,
20
22
  requireParams: !0
21
23
  });
22
- let { t: P } = M(), F = A(), { basePath: I = "/" } = e(), { withCurrentSearch: L } = n(), { data: R, isLoading: z, error: B } = t(N || ""), { data: V } = s({ workspaceId: N }, { limit: 1 }, N), { data: H } = a(N || "", { limit: 1 }), { data: U } = c(N), { canViewWorkspace: W, canUpdateWorkspace: G, canInviteMember: K, isLoading: q } = o();
23
- if (q) return /* @__PURE__ */ v("div", {
24
+ let { t: B } = R(), V = I(), { basePath: H = "/" } = e(), { withCurrentSearch: U } = n(), [W, G] = s(!1), [K, q] = s(null), { mutate: J, isPending: Y } = a(), { data: X, isLoading: ae, error: oe } = t(z || ""), { data: se } = i({ workspaceId: z }, { limit: 1 }, z), { data: ce } = te(z || "", { limit: 1 }), { data: le } = o(z), { canViewWorkspace: ue, canUpdateWorkspace: Z, canArchiveWorkspace: de, canInviteMember: Q, isLoading: fe } = ne();
25
+ if (fe) return /* @__PURE__ */ v("div", {
24
26
  className: "space-y-4 sm:space-y-6 p-3 sm:p-6",
25
- children: [/* @__PURE__ */ _(k, { className: "h-10 w-1/3" }), /* @__PURE__ */ v("div", {
27
+ children: [/* @__PURE__ */ _(F, { className: "h-10 w-1/3" }), /* @__PURE__ */ v("div", {
26
28
  className: "grid grid-cols-1 md:grid-cols-3 gap-4",
27
29
  children: [
28
- /* @__PURE__ */ _(k, { className: "h-32" }),
29
- /* @__PURE__ */ _(k, { className: "h-32" }),
30
- /* @__PURE__ */ _(k, { className: "h-32" })
30
+ /* @__PURE__ */ _(F, { className: "h-32" }),
31
+ /* @__PURE__ */ _(F, { className: "h-32" }),
32
+ /* @__PURE__ */ _(F, { className: "h-32" })
31
33
  ]
32
34
  })]
33
35
  });
34
- if (!W) return /* @__PURE__ */ _("div", {
36
+ if (!ue) return /* @__PURE__ */ _("div", {
35
37
  className: "flex items-center justify-center min-h-[400px]",
36
38
  children: /* @__PURE__ */ v("div", {
37
39
  className: "text-center space-y-2",
38
40
  children: [/* @__PURE__ */ _("h2", {
39
41
  className: "text-lg font-semibold",
40
- children: r(P, "workspaceDetail.accessDenied", "Access Denied")
42
+ children: r(B, "workspaceDetail.accessDenied", "Access Denied")
41
43
  }), /* @__PURE__ */ _("p", {
42
44
  className: "text-sm text-text-secondary",
43
- children: r(P, "workspaceDetail.accessDeniedDesc", "You don't have permission to view this workspace.")
45
+ children: r(B, "workspaceDetail.accessDeniedDesc", "You don't have permission to view this workspace.")
44
46
  })]
45
47
  })
46
48
  });
47
- if (z) return /* @__PURE__ */ v("div", {
49
+ if (ae) return /* @__PURE__ */ v("div", {
48
50
  className: "space-y-4 sm:space-y-6 p-3 sm:p-6",
49
- children: [/* @__PURE__ */ _(k, { className: "h-10 w-1/3" }), /* @__PURE__ */ v("div", {
51
+ children: [/* @__PURE__ */ _(F, { className: "h-10 w-1/3" }), /* @__PURE__ */ v("div", {
50
52
  className: "grid grid-cols-1 md:grid-cols-3 gap-4",
51
53
  children: [
52
- /* @__PURE__ */ _(k, { className: "h-32" }),
53
- /* @__PURE__ */ _(k, { className: "h-32" }),
54
- /* @__PURE__ */ _(k, { className: "h-32" })
54
+ /* @__PURE__ */ _(F, { className: "h-32" }),
55
+ /* @__PURE__ */ _(F, { className: "h-32" }),
56
+ /* @__PURE__ */ _(F, { className: "h-32" })
55
57
  ]
56
58
  })]
57
59
  });
58
- if (B || !R) return /* @__PURE__ */ v("div", {
60
+ if (oe || !X) return /* @__PURE__ */ v("div", {
59
61
  className: "space-y-4 p-6",
60
- children: [/* @__PURE__ */ v(b, {
62
+ children: [/* @__PURE__ */ v(D, {
61
63
  variant: "ghost",
62
- onClick: () => F(L(`${I}/list`)),
64
+ onClick: () => V(U(`${H}/list`)),
63
65
  className: "gap-2",
64
- children: [/* @__PURE__ */ _(u, { size: 20 }), r(P, "workspaceDetail.backToWorkspaces", "Back to Workspaces")]
65
- }), /* @__PURE__ */ _(E, {
66
+ children: [/* @__PURE__ */ _(u, { size: 20 }), r(B, "workspaceDetail.backToWorkspaces", "Back to Workspaces")]
67
+ }), /* @__PURE__ */ _(M, {
66
68
  illustration: "empty-search",
67
- title: r(P, "workspaceDetail.notFound", "Workspace not found"),
68
- description: r(P, "workspaceDetail.notFoundDescription", "This workspace doesn't exist or you don't have permission to view it.")
69
+ title: r(B, "workspaceDetail.notFound", "Workspace not found"),
70
+ description: r(B, "workspaceDetail.notFoundDescription", "This workspace doesn't exist or you don't have permission to view it.")
69
71
  })]
70
72
  });
71
- let J = (e, t) => {
72
- (e.key === "Enter" || e.key === " ") && (e.preventDefault(), F(t));
73
+ let $ = (e, t) => {
74
+ (e.key === "Enter" || e.key === " ") && (e.preventDefault(), V(t));
75
+ }, pe = () => {
76
+ z && (q(null), J(z, {
77
+ onSuccess: () => {
78
+ G(!1), V(U(`${H}/list`));
79
+ },
80
+ onError: () => {
81
+ q(r(B, "workspaceDetail.archiveFailed", "The workspace could not be archived. Please try again."));
82
+ }
83
+ }));
73
84
  };
74
85
  return /* @__PURE__ */ v("div", {
75
86
  className: "space-y-4 sm:space-y-6 p-3 sm:p-6",
@@ -77,71 +88,75 @@ function N() {
77
88
  /* @__PURE__ */ v("div", {
78
89
  className: "flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3",
79
90
  children: [/* @__PURE__ */ v("div", { children: [
80
- /* @__PURE__ */ v(b, {
91
+ /* @__PURE__ */ v(D, {
81
92
  variant: "ghost",
82
- onClick: () => F(L(`${I}/list`)),
93
+ onClick: () => V(U(`${H}/list`)),
83
94
  className: "gap-2 mb-2 -ml-2",
84
- children: [/* @__PURE__ */ _(u, { size: 20 }), r(P, "workspaceDetail.backToWorkspaces", "Back to Workspaces")]
95
+ children: [/* @__PURE__ */ _(u, { size: 20 }), r(B, "workspaceDetail.backToWorkspaces", "Back to Workspaces")]
85
96
  }),
86
97
  /* @__PURE__ */ _("h1", {
87
98
  className: "text-2xl sm:text-3xl font-bold",
88
- children: R.name
99
+ children: X.name
89
100
  }),
90
101
  /* @__PURE__ */ v("div", {
91
102
  className: "flex items-center gap-2 mt-2",
92
- children: [/* @__PURE__ */ _(y, {
103
+ children: [/* @__PURE__ */ _(E, {
93
104
  variant: "outline",
94
- children: R.type
95
- }), /* @__PURE__ */ _(y, { children: R.status })]
105
+ children: X.type
106
+ }), /* @__PURE__ */ _(E, { children: X.status })]
96
107
  })
97
- ] }), /* @__PURE__ */ _(x, {
98
- primary: G ? {
99
- label: r(P, "workspaceDetail.settings", "Settings"),
108
+ ] }), /* @__PURE__ */ _(ie, {
109
+ primary: Z ? {
110
+ label: r(B, "workspaceDetail.settings", "Settings"),
100
111
  icon: /* @__PURE__ */ _(p, { size: 18 }),
101
- onSelect: () => F(L(`${I}/${N}/settings`))
102
- } : K ? {
103
- label: r(P, "workspaceDetail.inviteMembers", "Invite Member"),
112
+ onSelect: () => V(U(`${H}/${z}/settings`))
113
+ } : Q ? {
114
+ label: r(B, "workspaceDetail.inviteMembers", "Invite Member"),
104
115
  icon: /* @__PURE__ */ _(m, { size: 18 }),
105
- onSelect: () => F(L(`${I}/${N}/invite`))
116
+ onSelect: () => V(U(`${H}/${z}/invite`))
106
117
  } : void 0,
107
- actions: [...G && K ? [{
108
- label: r(P, "workspaceDetail.inviteMembers", "Invite Member"),
118
+ actions: [...Z && Q ? [{
119
+ label: r(B, "workspaceDetail.inviteMembers", "Invite Member"),
109
120
  icon: /* @__PURE__ */ _(m, { size: 16 }),
110
- onSelect: () => F(L(`${I}/${N}/invite`))
121
+ onSelect: () => V(U(`${H}/${z}/invite`))
122
+ }] : [], ...de ? [{
123
+ label: r(B, "workspaceDetail.archiveWorkspace", "Archive Workspace"),
124
+ icon: /* @__PURE__ */ _(l, { size: 16 }),
125
+ onSelect: () => G(!0)
111
126
  }] : []]
112
127
  })]
113
128
  }),
114
- /* @__PURE__ */ _(O, { children: r(P, "workspaceDetail.purpose", "This is the home for a single workspace — the hub that ties together its projects, the people who collaborate in it, and everything that happens inside. Use the cards below to jump into work, manage who has access, or review recent activity.") }),
115
- /* @__PURE__ */ _(D, {
129
+ /* @__PURE__ */ _(P, { children: r(B, "workspaceDetail.purpose", "This is the home for a single workspace — the hub that ties together its projects, the people who collaborate in it, and everything that happens inside. Use the cards below to jump into work, manage who has access, or review recent activity.") }),
130
+ /* @__PURE__ */ _(N, {
116
131
  storageKey: "workspaces-workspace-detail",
117
132
  steps: [
118
133
  {
119
134
  id: "open-projects",
120
- label: r(P, "workspaceDetail.stepProjects", "Open the projects board"),
121
- description: r(P, "workspaceDetail.stepProjectsDesc", "Projects are where the actual work lives — start or pick one up."),
135
+ label: r(B, "workspaceDetail.stepProjects", "Open the projects board"),
136
+ description: r(B, "workspaceDetail.stepProjectsDesc", "Projects are where the actual work lives — start or pick one up."),
122
137
  icon: /* @__PURE__ */ _(f, { size: 16 }),
123
- onClick: () => F(L(`${I}/${N}/projects`))
138
+ onClick: () => V(U(`${H}/${z}/projects`))
124
139
  },
125
- ...K ? [{
140
+ ...Q ? [{
126
141
  id: "invite-member",
127
- label: r(P, "workspaceDetail.stepInvite", "Invite a teammate"),
128
- description: r(P, "workspaceDetail.stepInviteDesc", "Bring people into this workspace so they can collaborate."),
142
+ label: r(B, "workspaceDetail.stepInvite", "Invite a teammate"),
143
+ description: r(B, "workspaceDetail.stepInviteDesc", "Bring people into this workspace so they can collaborate."),
129
144
  icon: /* @__PURE__ */ _(m, { size: 16 }),
130
- onClick: () => F(L(`${I}/${N}/invite`))
145
+ onClick: () => V(U(`${H}/${z}/invite`))
131
146
  }] : [],
132
147
  {
133
148
  id: "review-members",
134
- label: r(P, "workspaceDetail.stepMembers", "Review who has access"),
135
- description: r(P, "workspaceDetail.stepMembersDesc", "Check the current members and their roles."),
149
+ label: r(B, "workspaceDetail.stepMembers", "Review who has access"),
150
+ description: r(B, "workspaceDetail.stepMembersDesc", "Check the current members and their roles."),
136
151
  icon: /* @__PURE__ */ _(h, { size: 16 }),
137
- onClick: () => F(L(`${I}/${N}/members`))
152
+ onClick: () => V(U(`${H}/${z}/members`))
138
153
  },
139
- ...G ? [{
154
+ ...Z ? [{
140
155
  id: "configure-settings",
141
- label: r(P, "workspaceDetail.stepSettings", "Configure workspace settings"),
142
- description: r(P, "workspaceDetail.stepSettingsDesc", "Set the name, domain and contact details for this workspace."),
156
+ label: r(B, "workspaceDetail.stepSettings", "Configure workspace settings"),
157
+ description: r(B, "workspaceDetail.stepSettingsDesc", "Set the name, domain and contact details for this workspace."),
143
158
  icon: /* @__PURE__ */ _(p, { size: 16 }),
144
- onClick: () => F(L(`${I}/${N}/settings`))
159
+ onClick: () => V(U(`${H}/${z}/settings`))
145
160
  }] : []
146
161
  ]
147
162
  }),
@@ -152,144 +167,167 @@ function N() {
152
167
  children: /* @__PURE__ */ v("div", {
153
168
  className: "grid grid-cols-1 sm:grid-cols-3 gap-4",
154
169
  children: [
155
- /* @__PURE__ */ v(T, {
170
+ /* @__PURE__ */ v(j, {
156
171
  treatment: "metric",
157
172
  glow: !0,
158
173
  className: "cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-action-primary-bg/50",
159
- onClick: () => F(L(`${I}/${N}/projects`)),
174
+ onClick: () => V(U(`${H}/${z}/projects`)),
160
175
  role: "button",
161
176
  tabIndex: 0,
162
- onKeyDown: (e) => J(e, L(`${I}/${N}/projects`)),
163
- children: [/* @__PURE__ */ v(C, {
177
+ onKeyDown: (e) => $(e, U(`${H}/${z}/projects`)),
178
+ children: [/* @__PURE__ */ v(k, {
164
179
  className: "flex flex-row items-center justify-between pb-2",
165
- children: [/* @__PURE__ */ v(w, {
180
+ children: [/* @__PURE__ */ v(A, {
166
181
  className: "flex items-center gap-2 text-text-secondary text-sm font-medium",
167
182
  children: [/* @__PURE__ */ _(f, {
168
183
  size: 18,
169
184
  className: "text-text-muted"
170
- }), r(P, "workspaceDetail.projects", "Projects")]
185
+ }), r(B, "workspaceDetail.projects", "Projects")]
171
186
  }), /* @__PURE__ */ _(d, {
172
187
  size: 18,
173
188
  className: "text-text-muted"
174
189
  })]
175
- }), /* @__PURE__ */ v(S, { children: [/* @__PURE__ */ _("p", {
190
+ }), /* @__PURE__ */ v(O, { children: [/* @__PURE__ */ _("p", {
176
191
  className: "text-3xl font-bold tabular-nums",
177
- children: V?.total ?? R.projectCount ?? 0
192
+ children: se?.total ?? X.projectCount ?? 0
178
193
  }), /* @__PURE__ */ _("p", {
179
194
  className: "text-sm text-text-muted",
180
- children: r(P, "workspaceDetail.projectsDesc", "Projects in this workspace")
195
+ children: r(B, "workspaceDetail.projectsDesc", "Projects in this workspace")
181
196
  })] })]
182
197
  }),
183
- /* @__PURE__ */ v(T, {
198
+ /* @__PURE__ */ v(j, {
184
199
  treatment: "metric",
185
200
  className: "cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-action-primary-bg/50",
186
- onClick: () => F(L(`${I}/${N}/members`)),
201
+ onClick: () => V(U(`${H}/${z}/members`)),
187
202
  role: "button",
188
203
  tabIndex: 0,
189
- onKeyDown: (e) => J(e, L(`${I}/${N}/members`)),
190
- children: [/* @__PURE__ */ v(C, {
204
+ onKeyDown: (e) => $(e, U(`${H}/${z}/members`)),
205
+ children: [/* @__PURE__ */ v(k, {
191
206
  className: "flex flex-row items-center justify-between pb-2",
192
- children: [/* @__PURE__ */ v(w, {
207
+ children: [/* @__PURE__ */ v(A, {
193
208
  className: "flex items-center gap-2 text-text-secondary text-sm font-medium",
194
209
  children: [/* @__PURE__ */ _(h, {
195
210
  size: 18,
196
211
  className: "text-text-muted"
197
- }), r(P, "workspaceDetail.members", "Members")]
212
+ }), r(B, "workspaceDetail.members", "Members")]
198
213
  }), /* @__PURE__ */ _(d, {
199
214
  size: 18,
200
215
  className: "text-text-muted"
201
216
  })]
202
- }), /* @__PURE__ */ v(S, { children: [/* @__PURE__ */ _("p", {
217
+ }), /* @__PURE__ */ v(O, { children: [/* @__PURE__ */ _("p", {
203
218
  className: "text-3xl font-bold tabular-nums",
204
- children: H?.total ?? R.memberCount ?? 0
219
+ children: ce?.total ?? X.memberCount ?? 0
205
220
  }), /* @__PURE__ */ _("p", {
206
221
  className: "text-sm text-text-muted",
207
- children: r(P, "workspaceDetail.membersDesc", "Workspace members")
222
+ children: r(B, "workspaceDetail.membersDesc", "Workspace members")
208
223
  })] })]
209
224
  }),
210
- /* @__PURE__ */ v(T, {
225
+ /* @__PURE__ */ v(j, {
211
226
  treatment: "metric",
212
227
  className: "cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-action-primary-bg/50",
213
- onClick: () => F(L(`${I}/${N}/activity`)),
228
+ onClick: () => V(U(`${H}/${z}/activity`)),
214
229
  role: "button",
215
230
  tabIndex: 0,
216
- onKeyDown: (e) => J(e, L(`${I}/${N}/activity`)),
217
- children: [/* @__PURE__ */ v(C, {
231
+ onKeyDown: (e) => $(e, U(`${H}/${z}/activity`)),
232
+ children: [/* @__PURE__ */ v(k, {
218
233
  className: "flex flex-row items-center justify-between pb-2",
219
- children: [/* @__PURE__ */ v(w, {
234
+ children: [/* @__PURE__ */ v(A, {
220
235
  className: "flex items-center gap-2 text-text-secondary text-sm font-medium",
221
- children: [/* @__PURE__ */ _(l, {
236
+ children: [/* @__PURE__ */ _(c, {
222
237
  size: 18,
223
238
  className: "text-text-muted"
224
- }), r(P, "workspaceDetail.activity", "Activity")]
239
+ }), r(B, "workspaceDetail.activity", "Activity")]
225
240
  }), /* @__PURE__ */ _(d, {
226
241
  size: 18,
227
242
  className: "text-text-muted"
228
243
  })]
229
- }), /* @__PURE__ */ v(S, { children: [/* @__PURE__ */ _("p", {
244
+ }), /* @__PURE__ */ v(O, { children: [/* @__PURE__ */ _("p", {
230
245
  className: "text-3xl font-bold tabular-nums",
231
- children: U?.length ?? 0
246
+ children: le?.length ?? 0
232
247
  }), /* @__PURE__ */ _("p", {
233
248
  className: "text-sm text-text-muted",
234
- children: r(P, "workspaceDetail.activityDesc", "Recent activity items")
249
+ children: r(B, "workspaceDetail.activityDesc", "Recent activity items")
235
250
  })] })]
236
251
  })
237
252
  ]
238
253
  })
239
254
  }), /* @__PURE__ */ _("aside", {
240
255
  className: "lg:sticky lg:top-6 lg:self-start",
241
- children: /* @__PURE__ */ v(T, {
256
+ children: /* @__PURE__ */ v(j, {
242
257
  treatment: "plain",
243
258
  className: "border-border-seam",
244
- children: [/* @__PURE__ */ _(C, { children: /* @__PURE__ */ _(w, { children: r(P, "workspaceDetail.workspaceInformation", "Workspace Information") }) }), /* @__PURE__ */ _(S, {
259
+ children: [/* @__PURE__ */ _(k, { children: /* @__PURE__ */ _(A, { children: r(B, "workspaceDetail.workspaceInformation", "Workspace Information") }) }), /* @__PURE__ */ _(O, {
245
260
  className: "space-y-2",
246
261
  children: /* @__PURE__ */ v("div", {
247
262
  className: "grid grid-cols-2 gap-2 text-sm",
248
263
  children: [
249
264
  /* @__PURE__ */ _("span", {
250
265
  className: "text-text-muted",
251
- children: r(P, "workspaceDetail.id", "ID:")
266
+ children: r(B, "workspaceDetail.id", "ID:")
252
267
  }),
253
268
  /* @__PURE__ */ _("span", {
254
269
  className: "font-mono text-xs break-all",
255
- children: R.id
270
+ children: X.id
256
271
  }),
257
- R.domain && /* @__PURE__ */ v(g, { children: [/* @__PURE__ */ _("span", {
272
+ X.domain && /* @__PURE__ */ v(g, { children: [/* @__PURE__ */ _("span", {
258
273
  className: "text-text-muted",
259
- children: r(P, "workspaceDetail.domain", "Domain:")
260
- }), /* @__PURE__ */ _("span", { children: R.domain })] }),
261
- R.contactEmail && /* @__PURE__ */ v(g, { children: [/* @__PURE__ */ _("span", {
274
+ children: r(B, "workspaceDetail.domain", "Domain:")
275
+ }), /* @__PURE__ */ _("span", { children: X.domain })] }),
276
+ X.contactEmail && /* @__PURE__ */ v(g, { children: [/* @__PURE__ */ _("span", {
262
277
  className: "text-text-muted",
263
- children: r(P, "workspaceDetail.contactEmail", "Contact Email:")
278
+ children: r(B, "workspaceDetail.contactEmail", "Contact Email:")
264
279
  }), /* @__PURE__ */ _("span", {
265
280
  className: "break-all",
266
- children: R.contactEmail
281
+ children: X.contactEmail
267
282
  })] }),
268
- R.website && /* @__PURE__ */ v(g, { children: [/* @__PURE__ */ _("span", {
283
+ X.website && /* @__PURE__ */ v(g, { children: [/* @__PURE__ */ _("span", {
269
284
  className: "text-text-muted",
270
- children: r(P, "workspaceDetail.website", "Website:")
285
+ children: r(B, "workspaceDetail.website", "Website:")
271
286
  }), /* @__PURE__ */ _("a", {
272
- href: R.website,
287
+ href: X.website,
273
288
  target: "_blank",
274
289
  rel: "noopener noreferrer",
275
290
  className: "text-primary hover:underline transition-colors duration-200 break-all",
276
- children: R.website
291
+ children: X.website
277
292
  })] }),
278
293
  /* @__PURE__ */ _("span", {
279
294
  className: "text-text-muted",
280
- children: r(P, "workspaceDetail.created", "Created:")
295
+ children: r(B, "workspaceDetail.created", "Created:")
281
296
  }),
282
- /* @__PURE__ */ _("span", { children: new Date(R.createdAt).toLocaleDateString() })
297
+ /* @__PURE__ */ _("span", { children: new Date(X.createdAt).toLocaleDateString() })
283
298
  ]
284
299
  })
285
300
  })]
286
301
  })
287
302
  })]
303
+ }),
304
+ /* @__PURE__ */ _(y, {
305
+ open: W,
306
+ onOpenChange: (e) => {
307
+ G(e), e || q(null);
308
+ },
309
+ children: /* @__PURE__ */ v(S, { children: [
310
+ /* @__PURE__ */ v(w, { children: [/* @__PURE__ */ _(T, { children: r(B, "workspaceDetail.archiveTitle", "Archive workspace?") }), /* @__PURE__ */ _(re, { children: r(B, "workspaceDetail.archiveDescription", "This removes the workspace from active work while preserving its data.") })] }),
311
+ K && /* @__PURE__ */ _("p", {
312
+ className: "text-sm text-status-error-text",
313
+ children: K
314
+ }),
315
+ /* @__PURE__ */ v(C, { children: [/* @__PURE__ */ _(x, {
316
+ disabled: Y,
317
+ children: r(B, "common.cancel", "Cancel")
318
+ }), /* @__PURE__ */ _(b, {
319
+ disabled: Y,
320
+ onClick: (e) => {
321
+ e.preventDefault(), pe();
322
+ },
323
+ children: Y ? r(B, "workspaceDetail.archiving", "Archiving...") : r(B, "workspaceDetail.archive", "Archive")
324
+ })] })
325
+ ] })
288
326
  })
289
327
  ]
290
328
  });
291
329
  }
292
330
  //#endregion
293
- export { N as WorkspaceDetailPage };
331
+ export { z as WorkspaceDetailPage };
294
332
 
295
333
  //# sourceMappingURL=WorkspaceDetailPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"WorkspaceDetailPage.js","names":[],"sources":["../../src/pages/WorkspaceDetailPage.tsx"],"sourcesContent":["import { useParams, useNavigate } from 'react-router';\nimport {\n Settings,\n ArrowLeft,\n FolderKanban,\n Users,\n Activity,\n ChevronRight,\n UserPlus,\n} from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { tWithFallback } from '../utils/i18n';\nimport {\n Button,\n GlassCard,\n CardHeader,\n CardTitle,\n CardContent,\n Badge,\n Skeleton,\n CTAOverflowMenu,\n IllustratedEmptyState,\n PagePurpose,\n NextSteps,\n} from '@burdenoff/fe-libs/ui';\nimport { useWorkspace } from '../hooks/useWorkspaces';\nimport { useProjects } from '../hooks/useProjects';\nimport { useWorkspaceMembers } from '../hooks/useWorkspaceMembers';\nimport { useWorkspaceActivity } from '../hooks/useWorkspaceActivity';\nimport { useWorkspacesContext } from '../providers/WorkspacesProvider';\nimport { useScopedNavigation } from '../hooks/useScopedNavigation';\nimport { useWorkspacePermissions } from '../hooks/useWorkspacePermissions';\nimport { useWorkspacesPageView } from '../hooks/useWorkspacesPageView';\n\nexport function WorkspaceDetailPage() {\n const { workspaceId } = useParams<{ workspaceId: string }>();\n useWorkspacesPageView('workspaces.detail', { workspaceId, requireParams: true });\n const { t } = useI18n();\n const navigate = useNavigate();\n const { basePath = '/' } = useWorkspacesContext();\n const { withCurrentSearch } = useScopedNavigation();\n const { data: workspace, isLoading, error } = useWorkspace(workspaceId || '');\n const { data: projects } = useProjects({ workspaceId }, { limit: 1 }, workspaceId);\n const { data: members } = useWorkspaceMembers(workspaceId || '', { limit: 1 });\n const { data: activities } = useWorkspaceActivity(workspaceId);\n const {\n canViewWorkspace,\n canUpdateWorkspace,\n canInviteMember,\n isLoading: permissionsLoading,\n } = useWorkspacePermissions();\n\n if (permissionsLoading) {\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n <Skeleton className=\"h-10 w-1/3\" />\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <Skeleton className=\"h-32\" />\n <Skeleton className=\"h-32\" />\n <Skeleton className=\"h-32\" />\n </div>\n </div>\n );\n }\n\n if (!canViewWorkspace) {\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <h2 className=\"text-lg font-semibold\">\n {tWithFallback(t, 'workspaceDetail.accessDenied', 'Access Denied')}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {tWithFallback(\n t,\n 'workspaceDetail.accessDeniedDesc',\n \"You don't have permission to view this workspace.\"\n )}\n </p>\n </div>\n </div>\n );\n }\n\n if (isLoading) {\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n <Skeleton className=\"h-10 w-1/3\" />\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <Skeleton className=\"h-32\" />\n <Skeleton className=\"h-32\" />\n <Skeleton className=\"h-32\" />\n </div>\n </div>\n );\n }\n\n if (error || !workspace) {\n return (\n <div className=\"space-y-4 p-6\">\n <Button\n variant=\"ghost\"\n onClick={() => navigate(withCurrentSearch(`${basePath}/list`))}\n className=\"gap-2\"\n >\n <ArrowLeft size={20} />\n {tWithFallback(t, 'workspaceDetail.backToWorkspaces', 'Back to Workspaces')}\n </Button>\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title={tWithFallback(t, 'workspaceDetail.notFound', 'Workspace not found')}\n description={tWithFallback(\n t,\n 'workspaceDetail.notFoundDescription',\n \"This workspace doesn't exist or you don't have permission to view it.\"\n )}\n />\n </div>\n );\n }\n\n const handleCardKeyDown = (e: React.KeyboardEvent, path: string) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n navigate(path);\n }\n };\n\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n {/* Header */}\n <div className=\"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3\">\n <div>\n <Button\n variant=\"ghost\"\n onClick={() => navigate(withCurrentSearch(`${basePath}/list`))}\n className=\"gap-2 mb-2 -ml-2\"\n >\n <ArrowLeft size={20} />\n {tWithFallback(t, 'workspaceDetail.backToWorkspaces', 'Back to Workspaces')}\n </Button>\n <h1 className=\"text-2xl sm:text-3xl font-bold\">{workspace.name}</h1>\n <div className=\"flex items-center gap-2 mt-2\">\n <Badge variant=\"outline\">{workspace.type}</Badge>\n <Badge>{workspace.status}</Badge>\n </div>\n </div>\n <CTAOverflowMenu\n primary={\n canUpdateWorkspace\n ? {\n label: tWithFallback(t, 'workspaceDetail.settings', 'Settings'),\n icon: <Settings size={18} />,\n onSelect: () =>\n navigate(withCurrentSearch(`${basePath}/${workspaceId}/settings`)),\n }\n : canInviteMember\n ? {\n label: tWithFallback(t, 'workspaceDetail.inviteMembers', 'Invite Member'),\n icon: <UserPlus size={18} />,\n onSelect: () =>\n navigate(withCurrentSearch(`${basePath}/${workspaceId}/invite`)),\n }\n : undefined\n }\n actions={[\n ...(canUpdateWorkspace && canInviteMember\n ? [\n {\n label: tWithFallback(t, 'workspaceDetail.inviteMembers', 'Invite Member'),\n icon: <UserPlus size={16} />,\n onSelect: () =>\n navigate(withCurrentSearch(`${basePath}/${workspaceId}/invite`)),\n },\n ]\n : []),\n ]}\n />\n </div>\n\n <PagePurpose>\n {tWithFallback(\n t,\n 'workspaceDetail.purpose',\n 'This is the home for a single workspace — the hub that ties together its projects, the people who collaborate in it, and everything that happens inside. Use the cards below to jump into work, manage who has access, or review recent activity.'\n )}\n </PagePurpose>\n\n <NextSteps\n storageKey=\"workspaces-workspace-detail\"\n steps={[\n {\n id: 'open-projects',\n label: tWithFallback(t, 'workspaceDetail.stepProjects', 'Open the projects board'),\n description: tWithFallback(\n t,\n 'workspaceDetail.stepProjectsDesc',\n 'Projects are where the actual work lives — start or pick one up.'\n ),\n icon: <FolderKanban size={16} />,\n onClick: () => navigate(withCurrentSearch(`${basePath}/${workspaceId}/projects`)),\n },\n ...(canInviteMember\n ? [\n {\n id: 'invite-member',\n label: tWithFallback(t, 'workspaceDetail.stepInvite', 'Invite a teammate'),\n description: tWithFallback(\n t,\n 'workspaceDetail.stepInviteDesc',\n 'Bring people into this workspace so they can collaborate.'\n ),\n icon: <UserPlus size={16} />,\n onClick: () => navigate(withCurrentSearch(`${basePath}/${workspaceId}/invite`)),\n },\n ]\n : []),\n {\n id: 'review-members',\n label: tWithFallback(t, 'workspaceDetail.stepMembers', 'Review who has access'),\n description: tWithFallback(\n t,\n 'workspaceDetail.stepMembersDesc',\n 'Check the current members and their roles.'\n ),\n icon: <Users size={16} />,\n onClick: () => navigate(withCurrentSearch(`${basePath}/${workspaceId}/members`)),\n },\n ...(canUpdateWorkspace\n ? [\n {\n id: 'configure-settings',\n label: tWithFallback(\n t,\n 'workspaceDetail.stepSettings',\n 'Configure workspace settings'\n ),\n description: tWithFallback(\n t,\n 'workspaceDetail.stepSettingsDesc',\n 'Set the name, domain and contact details for this workspace.'\n ),\n icon: <Settings size={16} />,\n onClick: () => navigate(withCurrentSearch(`${basePath}/${workspaceId}/settings`)),\n },\n ]\n : []),\n ]}\n />\n\n {/* Main + detail rail */}\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-4 sm:gap-6\">\n {/* Main: stat metrics */}\n <div className=\"lg:col-span-2 space-y-4 sm:space-y-6\">\n <div className=\"grid grid-cols-1 sm:grid-cols-3 gap-4\">\n <GlassCard\n treatment=\"metric\"\n glow\n className=\"cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-action-primary-bg/50\"\n onClick={() => navigate(withCurrentSearch(`${basePath}/${workspaceId}/projects`))}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) =>\n handleCardKeyDown(e, withCurrentSearch(`${basePath}/${workspaceId}/projects`))\n }\n >\n <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n <CardTitle className=\"flex items-center gap-2 text-text-secondary text-sm font-medium\">\n <FolderKanban size={18} className=\"text-text-muted\" />\n {tWithFallback(t, 'workspaceDetail.projects', 'Projects')}\n </CardTitle>\n <ChevronRight size={18} className=\"text-text-muted\" />\n </CardHeader>\n <CardContent>\n <p className=\"text-3xl font-bold tabular-nums\">\n {projects?.total ?? workspace.projectCount ?? 0}\n </p>\n <p className=\"text-sm text-text-muted\">\n {tWithFallback(t, 'workspaceDetail.projectsDesc', 'Projects in this workspace')}\n </p>\n </CardContent>\n </GlassCard>\n\n <GlassCard\n treatment=\"metric\"\n className=\"cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-action-primary-bg/50\"\n onClick={() => navigate(withCurrentSearch(`${basePath}/${workspaceId}/members`))}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) =>\n handleCardKeyDown(e, withCurrentSearch(`${basePath}/${workspaceId}/members`))\n }\n >\n <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n <CardTitle className=\"flex items-center gap-2 text-text-secondary text-sm font-medium\">\n <Users size={18} className=\"text-text-muted\" />\n {tWithFallback(t, 'workspaceDetail.members', 'Members')}\n </CardTitle>\n <ChevronRight size={18} className=\"text-text-muted\" />\n </CardHeader>\n <CardContent>\n <p className=\"text-3xl font-bold tabular-nums\">\n {members?.total ?? workspace.memberCount ?? 0}\n </p>\n <p className=\"text-sm text-text-muted\">\n {tWithFallback(t, 'workspaceDetail.membersDesc', 'Workspace members')}\n </p>\n </CardContent>\n </GlassCard>\n\n <GlassCard\n treatment=\"metric\"\n className=\"cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-action-primary-bg/50\"\n onClick={() => navigate(withCurrentSearch(`${basePath}/${workspaceId}/activity`))}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) =>\n handleCardKeyDown(e, withCurrentSearch(`${basePath}/${workspaceId}/activity`))\n }\n >\n <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n <CardTitle className=\"flex items-center gap-2 text-text-secondary text-sm font-medium\">\n <Activity size={18} className=\"text-text-muted\" />\n {tWithFallback(t, 'workspaceDetail.activity', 'Activity')}\n </CardTitle>\n <ChevronRight size={18} className=\"text-text-muted\" />\n </CardHeader>\n <CardContent>\n <p className=\"text-3xl font-bold tabular-nums\">{activities?.length ?? 0}</p>\n <p className=\"text-sm text-text-muted\">\n {tWithFallback(t, 'workspaceDetail.activityDesc', 'Recent activity items')}\n </p>\n </CardContent>\n </GlassCard>\n </div>\n </div>\n\n {/* Detail rail: workspace info */}\n <aside className=\"lg:sticky lg:top-6 lg:self-start\">\n <GlassCard treatment=\"plain\" className=\"border-border-seam\">\n <CardHeader>\n <CardTitle>\n {tWithFallback(t, 'workspaceDetail.workspaceInformation', 'Workspace Information')}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n <div className=\"grid grid-cols-2 gap-2 text-sm\">\n <span className=\"text-text-muted\">\n {tWithFallback(t, 'workspaceDetail.id', 'ID:')}\n </span>\n <span className=\"font-mono text-xs break-all\">{workspace.id}</span>\n\n {workspace.domain && (\n <>\n <span className=\"text-text-muted\">\n {tWithFallback(t, 'workspaceDetail.domain', 'Domain:')}\n </span>\n <span>{workspace.domain}</span>\n </>\n )}\n\n {workspace.contactEmail && (\n <>\n <span className=\"text-text-muted\">\n {tWithFallback(t, 'workspaceDetail.contactEmail', 'Contact Email:')}\n </span>\n <span className=\"break-all\">{workspace.contactEmail}</span>\n </>\n )}\n\n {workspace.website && (\n <>\n <span className=\"text-text-muted\">\n {tWithFallback(t, 'workspaceDetail.website', 'Website:')}\n </span>\n <a\n href={workspace.website}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary hover:underline transition-colors duration-200 break-all\"\n >\n {workspace.website}\n </a>\n </>\n )}\n\n <span className=\"text-text-muted\">\n {tWithFallback(t, 'workspaceDetail.created', 'Created:')}\n </span>\n <span>{new Date(workspace.createdAt).toLocaleDateString()}</span>\n </div>\n </CardContent>\n </GlassCard>\n </aside>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"WorkspaceDetailPage.js","names":[],"sources":["../../src/pages/WorkspaceDetailPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useParams, useNavigate } from 'react-router';\nimport {\n Settings,\n ArrowLeft,\n FolderKanban,\n Users,\n Activity,\n ChevronRight,\n UserPlus,\n Archive,\n} from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { tWithFallback } from '../utils/i18n';\nimport {\n Button,\n GlassCard,\n CardHeader,\n CardTitle,\n CardContent,\n Badge,\n Skeleton,\n CTAOverflowMenu,\n IllustratedEmptyState,\n PagePurpose,\n NextSteps,\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from '@burdenoff/fe-libs/ui';\nimport { useWorkspace } from '../hooks/useWorkspaces';\nimport { useProjects } from '../hooks/useProjects';\nimport { useWorkspaceMembers } from '../hooks/useWorkspaceMembers';\nimport { useWorkspaceActivity } from '../hooks/useWorkspaceActivity';\nimport { useWorkspacesContext } from '../providers/WorkspacesProvider';\nimport { useScopedNavigation } from '../hooks/useScopedNavigation';\nimport { useWorkspacePermissions } from '../hooks/useWorkspacePermissions';\nimport { useWorkspacesPageView } from '../hooks/useWorkspacesPageView';\nimport { useArchiveWorkspace } from '../hooks/useWorkspaceMutations';\n\nexport function WorkspaceDetailPage() {\n const { workspaceId } = useParams<{ workspaceId: string }>();\n useWorkspacesPageView('workspaces.detail', { workspaceId, requireParams: true });\n const { t } = useI18n();\n const navigate = useNavigate();\n const { basePath = '/' } = useWorkspacesContext();\n const { withCurrentSearch } = useScopedNavigation();\n const [showArchiveDialog, setShowArchiveDialog] = useState(false);\n const [archiveError, setArchiveError] = useState<string | null>(null);\n const { mutate: archiveWorkspace, isPending: isArchiving } = useArchiveWorkspace();\n const { data: workspace, isLoading, error } = useWorkspace(workspaceId || '');\n const { data: projects } = useProjects({ workspaceId }, { limit: 1 }, workspaceId);\n const { data: members } = useWorkspaceMembers(workspaceId || '', { limit: 1 });\n const { data: activities } = useWorkspaceActivity(workspaceId);\n const {\n canViewWorkspace,\n canUpdateWorkspace,\n canArchiveWorkspace,\n canInviteMember,\n isLoading: permissionsLoading,\n } = useWorkspacePermissions();\n\n if (permissionsLoading) {\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n <Skeleton className=\"h-10 w-1/3\" />\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <Skeleton className=\"h-32\" />\n <Skeleton className=\"h-32\" />\n <Skeleton className=\"h-32\" />\n </div>\n </div>\n );\n }\n\n if (!canViewWorkspace) {\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <h2 className=\"text-lg font-semibold\">\n {tWithFallback(t, 'workspaceDetail.accessDenied', 'Access Denied')}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {tWithFallback(\n t,\n 'workspaceDetail.accessDeniedDesc',\n \"You don't have permission to view this workspace.\"\n )}\n </p>\n </div>\n </div>\n );\n }\n\n if (isLoading) {\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n <Skeleton className=\"h-10 w-1/3\" />\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n <Skeleton className=\"h-32\" />\n <Skeleton className=\"h-32\" />\n <Skeleton className=\"h-32\" />\n </div>\n </div>\n );\n }\n\n if (error || !workspace) {\n return (\n <div className=\"space-y-4 p-6\">\n <Button\n variant=\"ghost\"\n onClick={() => navigate(withCurrentSearch(`${basePath}/list`))}\n className=\"gap-2\"\n >\n <ArrowLeft size={20} />\n {tWithFallback(t, 'workspaceDetail.backToWorkspaces', 'Back to Workspaces')}\n </Button>\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title={tWithFallback(t, 'workspaceDetail.notFound', 'Workspace not found')}\n description={tWithFallback(\n t,\n 'workspaceDetail.notFoundDescription',\n \"This workspace doesn't exist or you don't have permission to view it.\"\n )}\n />\n </div>\n );\n }\n\n const handleCardKeyDown = (e: React.KeyboardEvent, path: string) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n navigate(path);\n }\n };\n\n const handleArchive = () => {\n if (!workspaceId) return;\n setArchiveError(null);\n archiveWorkspace(workspaceId, {\n onSuccess: () => {\n setShowArchiveDialog(false);\n navigate(withCurrentSearch(`${basePath}/list`));\n },\n onError: () => {\n setArchiveError(\n tWithFallback(\n t,\n 'workspaceDetail.archiveFailed',\n 'The workspace could not be archived. Please try again.'\n )\n );\n },\n });\n };\n\n return (\n <div className=\"space-y-4 sm:space-y-6 p-3 sm:p-6\">\n {/* Header */}\n <div className=\"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3\">\n <div>\n <Button\n variant=\"ghost\"\n onClick={() => navigate(withCurrentSearch(`${basePath}/list`))}\n className=\"gap-2 mb-2 -ml-2\"\n >\n <ArrowLeft size={20} />\n {tWithFallback(t, 'workspaceDetail.backToWorkspaces', 'Back to Workspaces')}\n </Button>\n <h1 className=\"text-2xl sm:text-3xl font-bold\">{workspace.name}</h1>\n <div className=\"flex items-center gap-2 mt-2\">\n <Badge variant=\"outline\">{workspace.type}</Badge>\n <Badge>{workspace.status}</Badge>\n </div>\n </div>\n <CTAOverflowMenu\n primary={\n canUpdateWorkspace\n ? {\n label: tWithFallback(t, 'workspaceDetail.settings', 'Settings'),\n icon: <Settings size={18} />,\n onSelect: () =>\n navigate(withCurrentSearch(`${basePath}/${workspaceId}/settings`)),\n }\n : canInviteMember\n ? {\n label: tWithFallback(t, 'workspaceDetail.inviteMembers', 'Invite Member'),\n icon: <UserPlus size={18} />,\n onSelect: () =>\n navigate(withCurrentSearch(`${basePath}/${workspaceId}/invite`)),\n }\n : undefined\n }\n actions={[\n ...(canUpdateWorkspace && canInviteMember\n ? [\n {\n label: tWithFallback(t, 'workspaceDetail.inviteMembers', 'Invite Member'),\n icon: <UserPlus size={16} />,\n onSelect: () =>\n navigate(withCurrentSearch(`${basePath}/${workspaceId}/invite`)),\n },\n ]\n : []),\n ...(canArchiveWorkspace\n ? [\n {\n label: tWithFallback(\n t,\n 'workspaceDetail.archiveWorkspace',\n 'Archive Workspace'\n ),\n icon: <Archive size={16} />,\n onSelect: () => setShowArchiveDialog(true),\n },\n ]\n : []),\n ]}\n />\n </div>\n\n <PagePurpose>\n {tWithFallback(\n t,\n 'workspaceDetail.purpose',\n 'This is the home for a single workspace — the hub that ties together its projects, the people who collaborate in it, and everything that happens inside. Use the cards below to jump into work, manage who has access, or review recent activity.'\n )}\n </PagePurpose>\n\n <NextSteps\n storageKey=\"workspaces-workspace-detail\"\n steps={[\n {\n id: 'open-projects',\n label: tWithFallback(t, 'workspaceDetail.stepProjects', 'Open the projects board'),\n description: tWithFallback(\n t,\n 'workspaceDetail.stepProjectsDesc',\n 'Projects are where the actual work lives — start or pick one up.'\n ),\n icon: <FolderKanban size={16} />,\n onClick: () => navigate(withCurrentSearch(`${basePath}/${workspaceId}/projects`)),\n },\n ...(canInviteMember\n ? [\n {\n id: 'invite-member',\n label: tWithFallback(t, 'workspaceDetail.stepInvite', 'Invite a teammate'),\n description: tWithFallback(\n t,\n 'workspaceDetail.stepInviteDesc',\n 'Bring people into this workspace so they can collaborate.'\n ),\n icon: <UserPlus size={16} />,\n onClick: () => navigate(withCurrentSearch(`${basePath}/${workspaceId}/invite`)),\n },\n ]\n : []),\n {\n id: 'review-members',\n label: tWithFallback(t, 'workspaceDetail.stepMembers', 'Review who has access'),\n description: tWithFallback(\n t,\n 'workspaceDetail.stepMembersDesc',\n 'Check the current members and their roles.'\n ),\n icon: <Users size={16} />,\n onClick: () => navigate(withCurrentSearch(`${basePath}/${workspaceId}/members`)),\n },\n ...(canUpdateWorkspace\n ? [\n {\n id: 'configure-settings',\n label: tWithFallback(\n t,\n 'workspaceDetail.stepSettings',\n 'Configure workspace settings'\n ),\n description: tWithFallback(\n t,\n 'workspaceDetail.stepSettingsDesc',\n 'Set the name, domain and contact details for this workspace.'\n ),\n icon: <Settings size={16} />,\n onClick: () => navigate(withCurrentSearch(`${basePath}/${workspaceId}/settings`)),\n },\n ]\n : []),\n ]}\n />\n\n {/* Main + detail rail */}\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-4 sm:gap-6\">\n {/* Main: stat metrics */}\n <div className=\"lg:col-span-2 space-y-4 sm:space-y-6\">\n <div className=\"grid grid-cols-1 sm:grid-cols-3 gap-4\">\n <GlassCard\n treatment=\"metric\"\n glow\n className=\"cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-action-primary-bg/50\"\n onClick={() => navigate(withCurrentSearch(`${basePath}/${workspaceId}/projects`))}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) =>\n handleCardKeyDown(e, withCurrentSearch(`${basePath}/${workspaceId}/projects`))\n }\n >\n <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n <CardTitle className=\"flex items-center gap-2 text-text-secondary text-sm font-medium\">\n <FolderKanban size={18} className=\"text-text-muted\" />\n {tWithFallback(t, 'workspaceDetail.projects', 'Projects')}\n </CardTitle>\n <ChevronRight size={18} className=\"text-text-muted\" />\n </CardHeader>\n <CardContent>\n <p className=\"text-3xl font-bold tabular-nums\">\n {projects?.total ?? workspace.projectCount ?? 0}\n </p>\n <p className=\"text-sm text-text-muted\">\n {tWithFallback(t, 'workspaceDetail.projectsDesc', 'Projects in this workspace')}\n </p>\n </CardContent>\n </GlassCard>\n\n <GlassCard\n treatment=\"metric\"\n className=\"cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-action-primary-bg/50\"\n onClick={() => navigate(withCurrentSearch(`${basePath}/${workspaceId}/members`))}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) =>\n handleCardKeyDown(e, withCurrentSearch(`${basePath}/${workspaceId}/members`))\n }\n >\n <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n <CardTitle className=\"flex items-center gap-2 text-text-secondary text-sm font-medium\">\n <Users size={18} className=\"text-text-muted\" />\n {tWithFallback(t, 'workspaceDetail.members', 'Members')}\n </CardTitle>\n <ChevronRight size={18} className=\"text-text-muted\" />\n </CardHeader>\n <CardContent>\n <p className=\"text-3xl font-bold tabular-nums\">\n {members?.total ?? workspace.memberCount ?? 0}\n </p>\n <p className=\"text-sm text-text-muted\">\n {tWithFallback(t, 'workspaceDetail.membersDesc', 'Workspace members')}\n </p>\n </CardContent>\n </GlassCard>\n\n <GlassCard\n treatment=\"metric\"\n className=\"cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-action-primary-bg/50\"\n onClick={() => navigate(withCurrentSearch(`${basePath}/${workspaceId}/activity`))}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) =>\n handleCardKeyDown(e, withCurrentSearch(`${basePath}/${workspaceId}/activity`))\n }\n >\n <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n <CardTitle className=\"flex items-center gap-2 text-text-secondary text-sm font-medium\">\n <Activity size={18} className=\"text-text-muted\" />\n {tWithFallback(t, 'workspaceDetail.activity', 'Activity')}\n </CardTitle>\n <ChevronRight size={18} className=\"text-text-muted\" />\n </CardHeader>\n <CardContent>\n <p className=\"text-3xl font-bold tabular-nums\">{activities?.length ?? 0}</p>\n <p className=\"text-sm text-text-muted\">\n {tWithFallback(t, 'workspaceDetail.activityDesc', 'Recent activity items')}\n </p>\n </CardContent>\n </GlassCard>\n </div>\n </div>\n\n {/* Detail rail: workspace info */}\n <aside className=\"lg:sticky lg:top-6 lg:self-start\">\n <GlassCard treatment=\"plain\" className=\"border-border-seam\">\n <CardHeader>\n <CardTitle>\n {tWithFallback(t, 'workspaceDetail.workspaceInformation', 'Workspace Information')}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n <div className=\"grid grid-cols-2 gap-2 text-sm\">\n <span className=\"text-text-muted\">\n {tWithFallback(t, 'workspaceDetail.id', 'ID:')}\n </span>\n <span className=\"font-mono text-xs break-all\">{workspace.id}</span>\n\n {workspace.domain && (\n <>\n <span className=\"text-text-muted\">\n {tWithFallback(t, 'workspaceDetail.domain', 'Domain:')}\n </span>\n <span>{workspace.domain}</span>\n </>\n )}\n\n {workspace.contactEmail && (\n <>\n <span className=\"text-text-muted\">\n {tWithFallback(t, 'workspaceDetail.contactEmail', 'Contact Email:')}\n </span>\n <span className=\"break-all\">{workspace.contactEmail}</span>\n </>\n )}\n\n {workspace.website && (\n <>\n <span className=\"text-text-muted\">\n {tWithFallback(t, 'workspaceDetail.website', 'Website:')}\n </span>\n <a\n href={workspace.website}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary hover:underline transition-colors duration-200 break-all\"\n >\n {workspace.website}\n </a>\n </>\n )}\n\n <span className=\"text-text-muted\">\n {tWithFallback(t, 'workspaceDetail.created', 'Created:')}\n </span>\n <span>{new Date(workspace.createdAt).toLocaleDateString()}</span>\n </div>\n </CardContent>\n </GlassCard>\n </aside>\n </div>\n\n <AlertDialog\n open={showArchiveDialog}\n onOpenChange={(open) => {\n setShowArchiveDialog(open);\n if (!open) setArchiveError(null);\n }}\n >\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>\n {tWithFallback(t, 'workspaceDetail.archiveTitle', 'Archive workspace?')}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {tWithFallback(\n t,\n 'workspaceDetail.archiveDescription',\n 'This removes the workspace from active work while preserving its data.'\n )}\n </AlertDialogDescription>\n </AlertDialogHeader>\n {archiveError && <p className=\"text-sm text-status-error-text\">{archiveError}</p>}\n <AlertDialogFooter>\n <AlertDialogCancel disabled={isArchiving}>\n {tWithFallback(t, 'common.cancel', 'Cancel')}\n </AlertDialogCancel>\n <AlertDialogAction\n disabled={isArchiving}\n onClick={(event) => {\n event.preventDefault();\n handleArchive();\n }}\n >\n {isArchiving\n ? tWithFallback(t, 'workspaceDetail.archiving', 'Archiving...')\n : tWithFallback(t, 'workspaceDetail.archive', 'Archive')}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -547,7 +547,7 @@ function k() {
547
547
  }), /* @__PURE__ */ m(Oe, {
548
548
  id: "workspace-invite-email",
549
549
  type: "email",
550
- placeholder: "member@example.com",
550
+ placeholder: r(x, "workspaceInvite.emailPlaceholder", "member@example.com"),
551
551
  value: P,
552
552
  onChange: (e) => ot(e.target.value),
553
553
  disabled: q
@@ -653,7 +653,7 @@ function k() {
653
653
  t && Mt(t), e.target.value = "";
654
654
  },
655
655
  className: "hidden",
656
- "aria-label": "Choose CSV file"
656
+ "aria-label": r(x, "workspaceInvite.chooseCsvFileAriaLabel", "Choose CSV file")
657
657
  }),
658
658
  /* @__PURE__ */ m(_, {
659
659
  type: "button",