@burdenoff/microfe-organization 2026.624.2 → 2026.625.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.
- package/dist/organization-management/modules/members/components/BulkInviteForm.js.map +1 -1
- package/dist/organization-management/modules/members/pages/InviteMemberPage.js +58 -52
- package/dist/organization-management/modules/members/pages/InviteMemberPage.js.map +1 -1
- package/dist/organization-management/modules/members/pages/InvitePeoplePage.js +41 -39
- package/dist/organization-management/modules/members/pages/InvitePeoplePage.js.map +1 -1
- package/dist/organization-management/modules/members/pages/MemberDetailPage.js +70 -68
- package/dist/organization-management/modules/members/pages/MemberDetailPage.js.map +1 -1
- package/dist/organization-management/modules/members/pages/MembersListPage.js +232 -203
- package/dist/organization-management/modules/members/pages/MembersListPage.js.map +1 -1
- package/dist/organization-management/modules/members/pages/MyInvitesPage.js +38 -37
- package/dist/organization-management/modules/members/pages/MyInvitesPage.js.map +1 -1
- package/dist/organization-management/modules/members/pages/OrganizationInviteAcceptancePage.js +134 -132
- package/dist/organization-management/modules/members/pages/OrganizationInviteAcceptancePage.js.map +1 -1
- package/dist/organization-management/modules/organizations/pages/OrganizationCreatePage.js +38 -36
- package/dist/organization-management/modules/organizations/pages/OrganizationCreatePage.js.map +1 -1
- package/dist/organization-management/modules/organizations/pages/OrganizationDetailPage.js +163 -166
- package/dist/organization-management/modules/organizations/pages/OrganizationDetailPage.js.map +1 -1
- package/dist/organization-management/modules/organizations/pages/OrganizationEditPage.js +48 -46
- package/dist/organization-management/modules/organizations/pages/OrganizationEditPage.js.map +1 -1
- package/dist/organization-management/modules/organizations/pages/OrganizationsListPage.js +257 -229
- package/dist/organization-management/modules/organizations/pages/OrganizationsListPage.js.map +1 -1
- package/dist/organization-management/modules/workspaces/components/WorkspaceCard.js +43 -50
- package/dist/organization-management/modules/workspaces/components/WorkspaceCard.js.map +1 -1
- package/dist/organization-management/modules/workspaces/pages/WorkspaceCreatePage.js +39 -37
- package/dist/organization-management/modules/workspaces/pages/WorkspaceCreatePage.js.map +1 -1
- package/dist/organization-management/modules/workspaces/pages/WorkspaceDetailPage.js +146 -145
- package/dist/organization-management/modules/workspaces/pages/WorkspaceDetailPage.js.map +1 -1
- package/dist/organization-management/modules/workspaces/pages/WorkspaceEditPage.js +46 -44
- package/dist/organization-management/modules/workspaces/pages/WorkspaceEditPage.js.map +1 -1
- package/dist/organization-management/modules/workspaces/pages/WorkspacesListPage.js +115 -72
- package/dist/organization-management/modules/workspaces/pages/WorkspacesListPage.js.map +1 -1
- package/package.json +2 -2
|
@@ -11,11 +11,12 @@ import { useWorkspacesByOrganization as l } from "../../workspaces/hooks/useWork
|
|
|
11
11
|
import { WorkspaceCard as u } from "../../workspaces/components/WorkspaceCard.js";
|
|
12
12
|
import { useMemo as d, useState as f } from "react";
|
|
13
13
|
import { ArrowLeft as p, Briefcase as m, Building as h, Edit as g, UserPlus as _, Users as v } from "lucide-react";
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
14
|
+
import { CTAOverflowMenu as y, EmphasisPanel as b, GlassCard as x } from "@burdenoff/fe-libs/ui";
|
|
15
|
+
import { usePermissions as S } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
16
|
+
import { jsx as C, jsxs as w } from "react/jsx-runtime";
|
|
17
|
+
import { useParams as T } from "react-router-dom";
|
|
17
18
|
//#region src/organization-management/modules/organizations/pages/OrganizationDetailPage.tsx
|
|
18
|
-
function
|
|
19
|
+
function E(e) {
|
|
19
20
|
return new Date(e).toLocaleDateString("en-US", {
|
|
20
21
|
year: "numeric",
|
|
21
22
|
month: "long",
|
|
@@ -24,284 +25,280 @@ function C(e) {
|
|
|
24
25
|
minute: "2-digit"
|
|
25
26
|
});
|
|
26
27
|
}
|
|
27
|
-
function
|
|
28
|
-
let
|
|
29
|
-
c("organizations.detail", { organizationId:
|
|
30
|
-
let { navigate:
|
|
28
|
+
function D() {
|
|
29
|
+
let D = r(), { id: O } = T();
|
|
30
|
+
c("organizations.detail", { organizationId: O });
|
|
31
|
+
let { navigate: k, basePath: A = "/organizations" } = e(), { hasPermission: j, isLoading: M } = S(), { organization: N, loading: P, error: F } = t(O ?? ""), [I, L] = f("overview"), { workspaces: R, loading: z, error: B, refetch: V } = l(I === "workspaces" && O ? O ?? "" : "", 50, 0), H = d(() => [{
|
|
31
32
|
id: "overview",
|
|
32
|
-
label:
|
|
33
|
+
label: D("organizations.detail.tab.overview", "Overview")
|
|
33
34
|
}, {
|
|
34
35
|
id: "workspaces",
|
|
35
|
-
label: `${
|
|
36
|
+
label: `${D("organizations.detail.tab.workspaces", "Workspaces")} (${I === "workspaces" ? R.length : N?.workspaceCount ?? 0})`
|
|
36
37
|
}], [
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
I,
|
|
39
|
+
N?.workspaceCount,
|
|
40
|
+
D,
|
|
41
|
+
R.length
|
|
41
42
|
]);
|
|
42
|
-
return
|
|
43
|
+
return M ? /* @__PURE__ */ C("div", {
|
|
43
44
|
className: "min-h-full bg-[var(--color-bg-canvas)] p-6",
|
|
44
|
-
children: /* @__PURE__ */
|
|
45
|
-
}) :
|
|
45
|
+
children: /* @__PURE__ */ C(i, { message: D("common.loadingPermissions", "Loading permissions...") })
|
|
46
|
+
}) : j(s.ORG_READ) ? P ? /* @__PURE__ */ C("div", {
|
|
46
47
|
className: "min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6",
|
|
47
|
-
children: /* @__PURE__ */
|
|
48
|
-
}) :
|
|
48
|
+
children: /* @__PURE__ */ C(i, { message: D("organizations.detail.loading", "Loading organization details...") })
|
|
49
|
+
}) : F || !N ? /* @__PURE__ */ C("div", {
|
|
49
50
|
className: "min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6",
|
|
50
|
-
children: /* @__PURE__ */
|
|
51
|
-
message:
|
|
51
|
+
children: /* @__PURE__ */ C(a, {
|
|
52
|
+
message: F?.message || D("organizations.detail.notFound", "Organization not found"),
|
|
52
53
|
action: {
|
|
53
|
-
label:
|
|
54
|
-
onClick: () =>
|
|
54
|
+
label: D("organizations.create.back", "Back to Organizations"),
|
|
55
|
+
onClick: () => k(A)
|
|
55
56
|
}
|
|
56
57
|
})
|
|
57
|
-
}) : /* @__PURE__ */
|
|
58
|
+
}) : /* @__PURE__ */ C("div", {
|
|
58
59
|
className: "min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6 animate-in fade-in duration-200",
|
|
59
|
-
children: /* @__PURE__ */
|
|
60
|
+
children: /* @__PURE__ */ w("div", {
|
|
60
61
|
className: "mx-auto flex w-full max-w-7xl flex-col gap-6",
|
|
61
|
-
children: [/* @__PURE__ */
|
|
62
|
+
children: [/* @__PURE__ */ w("div", {
|
|
62
63
|
className: "space-y-4",
|
|
63
|
-
children: [/* @__PURE__ */
|
|
64
|
+
children: [/* @__PURE__ */ w("button", {
|
|
64
65
|
type: "button",
|
|
65
|
-
onClick: () =>
|
|
66
|
+
onClick: () => k(A),
|
|
66
67
|
className: "inline-flex min-h-10 items-center gap-2 text-[var(--color-text-secondary)] transition-all duration-200 hover:text-[var(--color-text-primary)]",
|
|
67
|
-
children: [/* @__PURE__ */
|
|
68
|
+
children: [/* @__PURE__ */ C(p, {
|
|
68
69
|
size: 20,
|
|
69
70
|
"aria-hidden": "true"
|
|
70
|
-
}), /* @__PURE__ */
|
|
71
|
+
}), /* @__PURE__ */ C("span", {
|
|
71
72
|
className: "text-sm font-medium",
|
|
72
|
-
children:
|
|
73
|
+
children: D("organizations.create.back", "Back to Organizations")
|
|
73
74
|
})]
|
|
74
|
-
}), /* @__PURE__ */
|
|
75
|
-
className: "flex flex-col gap-4
|
|
76
|
-
children: [/* @__PURE__ */
|
|
75
|
+
}), /* @__PURE__ */ w(b, {
|
|
76
|
+
className: "flex flex-col gap-4 p-5 lg:flex-row lg:items-start lg:justify-between",
|
|
77
|
+
children: [/* @__PURE__ */ w("div", {
|
|
77
78
|
className: "flex min-w-0 items-start gap-4",
|
|
78
|
-
children: [/* @__PURE__ */
|
|
79
|
+
children: [/* @__PURE__ */ C("div", {
|
|
79
80
|
className: "flex size-16 items-center justify-center rounded-xl bg-[var(--color-status-info-bgSubtle)] text-[var(--color-status-info-text)]",
|
|
80
|
-
children: /* @__PURE__ */
|
|
81
|
+
children: /* @__PURE__ */ C(h, {
|
|
81
82
|
size: 28,
|
|
82
83
|
"aria-hidden": "true"
|
|
83
84
|
})
|
|
84
|
-
}), /* @__PURE__ */
|
|
85
|
+
}), /* @__PURE__ */ w("div", {
|
|
85
86
|
className: "min-w-0 space-y-2",
|
|
86
87
|
children: [
|
|
87
|
-
/* @__PURE__ */
|
|
88
|
+
/* @__PURE__ */ w("div", {
|
|
88
89
|
className: "flex flex-wrap items-start gap-3",
|
|
89
|
-
children: [/* @__PURE__ */
|
|
90
|
+
children: [/* @__PURE__ */ C("h1", {
|
|
90
91
|
className: "text-3xl font-bold text-[var(--color-text-primary)]",
|
|
91
|
-
children:
|
|
92
|
-
}), /* @__PURE__ */
|
|
92
|
+
children: N.name
|
|
93
|
+
}), /* @__PURE__ */ C(n, { status: N.status })]
|
|
93
94
|
}),
|
|
94
|
-
/* @__PURE__ */
|
|
95
|
+
/* @__PURE__ */ w("p", {
|
|
95
96
|
className: "break-all font-mono text-sm text-[var(--color-text-secondary)]",
|
|
96
|
-
children: ["/",
|
|
97
|
+
children: ["/", N.slug]
|
|
97
98
|
}),
|
|
98
|
-
|
|
99
|
+
N.description ? /* @__PURE__ */ C("p", {
|
|
99
100
|
className: "max-w-2xl text-sm text-[var(--color-text-secondary)]",
|
|
100
|
-
children:
|
|
101
|
+
children: N.description
|
|
101
102
|
}) : null
|
|
102
103
|
]
|
|
103
104
|
})]
|
|
104
|
-
}), /* @__PURE__ */
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
className: "inline-flex min-h-11 items-center justify-center gap-2 rounded-lg border border-[var(--color-border-default)] px-4 py-2.5 text-[var(--color-text-primary)] transition-all duration-200 hover:bg-[var(--color-bg-subtle)]",
|
|
111
|
-
children: [/* @__PURE__ */ b(v, {
|
|
112
|
-
size: 16,
|
|
113
|
-
"aria-hidden": "true"
|
|
114
|
-
}), /* @__PURE__ */ b("span", { children: O(s.MEMBER_INVITE) ? w("organizations.detail.manageMembers", "Manage Members") : w("organizations.detail.viewMembers", "View Members") })]
|
|
105
|
+
}), /* @__PURE__ */ C(y, {
|
|
106
|
+
primary: j(s.ORG_UPDATE) ? {
|
|
107
|
+
label: D("organizations.edit.title", "Edit Organization"),
|
|
108
|
+
icon: /* @__PURE__ */ C(g, {
|
|
109
|
+
size: 16,
|
|
110
|
+
"aria-hidden": "true"
|
|
115
111
|
}),
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}), /* @__PURE__ */ b("span", { children: w("members.invite.button", "Invite Member") })]
|
|
112
|
+
onSelect: () => k(`${A}/${O}/edit`)
|
|
113
|
+
} : void 0,
|
|
114
|
+
actions: [...j(s.MEMBER_LIST) ? [{
|
|
115
|
+
label: j(s.MEMBER_INVITE) ? D("organizations.detail.manageMembers", "Manage Members") : D("organizations.detail.viewMembers", "View Members"),
|
|
116
|
+
icon: /* @__PURE__ */ C(v, {
|
|
117
|
+
size: 16,
|
|
118
|
+
"aria-hidden": "true"
|
|
124
119
|
}),
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
]
|
|
120
|
+
onSelect: () => k(`${A}/${O}/members`)
|
|
121
|
+
}] : [], ...j(s.MEMBER_INVITE) ? [{
|
|
122
|
+
label: D("members.invite.button", "Invite Member"),
|
|
123
|
+
icon: /* @__PURE__ */ C(_, {
|
|
124
|
+
size: 16,
|
|
125
|
+
"aria-hidden": "true"
|
|
126
|
+
}),
|
|
127
|
+
onSelect: () => k(`${A}/${O}/members/invite`)
|
|
128
|
+
}] : []]
|
|
135
129
|
})]
|
|
136
130
|
})]
|
|
137
|
-
}), /* @__PURE__ */ x
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
131
|
+
}), /* @__PURE__ */ w(x, {
|
|
132
|
+
treatment: "plain",
|
|
133
|
+
className: "border-border-seam p-0",
|
|
134
|
+
children: [/* @__PURE__ */ C("div", {
|
|
135
|
+
className: "overflow-x-auto border-b border-[var(--color-border-seam)]",
|
|
136
|
+
children: /* @__PURE__ */ C("div", {
|
|
142
137
|
className: "flex min-w-max gap-2 px-4 pt-4 sm:px-6",
|
|
143
|
-
children:
|
|
144
|
-
let t =
|
|
145
|
-
return /* @__PURE__ */
|
|
138
|
+
children: H.map((e) => {
|
|
139
|
+
let t = I === e.id;
|
|
140
|
+
return /* @__PURE__ */ C("button", {
|
|
146
141
|
type: "button",
|
|
147
|
-
onClick: () =>
|
|
142
|
+
onClick: () => L(e.id),
|
|
148
143
|
className: `inline-flex min-h-11 items-center rounded-t-lg border-b-2 px-4 py-3 text-sm font-medium transition-colors ${t ? "border-[var(--color-action-primary-bg)] text-[var(--color-action-primary-bg)]" : "border-transparent text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)]"}`,
|
|
149
144
|
"aria-pressed": t,
|
|
150
145
|
children: e.label
|
|
151
146
|
}, e.id);
|
|
152
147
|
})
|
|
153
148
|
})
|
|
154
|
-
}), /* @__PURE__ */
|
|
149
|
+
}), /* @__PURE__ */ C("div", {
|
|
155
150
|
className: "p-4 sm:p-6",
|
|
156
|
-
children:
|
|
151
|
+
children: I === "overview" ? /* @__PURE__ */ w("div", {
|
|
157
152
|
className: "grid grid-cols-1 gap-6 xl:grid-cols-[minmax(0,1fr)_320px]",
|
|
158
|
-
children: [/* @__PURE__ */ x
|
|
159
|
-
|
|
160
|
-
|
|
153
|
+
children: [/* @__PURE__ */ w(x, {
|
|
154
|
+
treatment: "plain",
|
|
155
|
+
className: "border-border-seam bg-[var(--color-bg-canvas)] p-5",
|
|
156
|
+
children: [/* @__PURE__ */ C("h2", {
|
|
161
157
|
className: "text-lg font-semibold text-[var(--color-text-primary)]",
|
|
162
|
-
children:
|
|
163
|
-
}), /* @__PURE__ */
|
|
158
|
+
children: D("organizations.detail.detailsSection", "Organization details")
|
|
159
|
+
}), /* @__PURE__ */ w("dl", {
|
|
164
160
|
className: "mt-5 grid grid-cols-1 gap-4 sm:grid-cols-2",
|
|
165
161
|
children: [
|
|
166
|
-
/* @__PURE__ */
|
|
162
|
+
/* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("dt", {
|
|
167
163
|
className: "text-sm font-medium text-[var(--color-text-secondary)]",
|
|
168
|
-
children:
|
|
169
|
-
}), /* @__PURE__ */
|
|
164
|
+
children: D("common.name", "Name")
|
|
165
|
+
}), /* @__PURE__ */ C("dd", {
|
|
170
166
|
className: "mt-1 text-sm text-[var(--color-text-primary)]",
|
|
171
|
-
children:
|
|
167
|
+
children: N.name
|
|
172
168
|
})] }),
|
|
173
|
-
/* @__PURE__ */
|
|
169
|
+
/* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("dt", {
|
|
174
170
|
className: "text-sm font-medium text-[var(--color-text-secondary)]",
|
|
175
|
-
children:
|
|
176
|
-
}), /* @__PURE__ */
|
|
171
|
+
children: D("common.slug", "Slug")
|
|
172
|
+
}), /* @__PURE__ */ C("dd", {
|
|
177
173
|
className: "mt-1 break-all font-mono text-sm text-[var(--color-text-primary)]",
|
|
178
|
-
children:
|
|
174
|
+
children: N.slug
|
|
179
175
|
})] }),
|
|
180
|
-
/* @__PURE__ */
|
|
176
|
+
/* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("dt", {
|
|
181
177
|
className: "text-sm font-medium text-[var(--color-text-secondary)]",
|
|
182
|
-
children:
|
|
183
|
-
}), /* @__PURE__ */
|
|
178
|
+
children: D("common.status", "Status")
|
|
179
|
+
}), /* @__PURE__ */ C("dd", {
|
|
184
180
|
className: "mt-1",
|
|
185
|
-
children: /* @__PURE__ */
|
|
181
|
+
children: /* @__PURE__ */ C(n, { status: N.status })
|
|
186
182
|
})] }),
|
|
187
|
-
/* @__PURE__ */
|
|
183
|
+
/* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("dt", {
|
|
188
184
|
className: "text-sm font-medium text-[var(--color-text-secondary)]",
|
|
189
|
-
children:
|
|
190
|
-
}), /* @__PURE__ */
|
|
185
|
+
children: D("organizations.detail.workspaceCount", "Workspace count")
|
|
186
|
+
}), /* @__PURE__ */ C("dd", {
|
|
191
187
|
className: "mt-1 text-sm text-[var(--color-text-primary)]",
|
|
192
|
-
children:
|
|
188
|
+
children: N.workspaceCount ?? 0
|
|
193
189
|
})] }),
|
|
194
|
-
|
|
190
|
+
N.website ? /* @__PURE__ */ w("div", {
|
|
195
191
|
className: "sm:col-span-2",
|
|
196
|
-
children: [/* @__PURE__ */
|
|
192
|
+
children: [/* @__PURE__ */ C("dt", {
|
|
197
193
|
className: "text-sm font-medium text-[var(--color-text-secondary)]",
|
|
198
|
-
children:
|
|
199
|
-
}), /* @__PURE__ */
|
|
194
|
+
children: D("organizations.detail.website", "Website")
|
|
195
|
+
}), /* @__PURE__ */ C("dd", {
|
|
200
196
|
className: "mt-1 break-all text-sm",
|
|
201
|
-
children: /* @__PURE__ */
|
|
202
|
-
href:
|
|
197
|
+
children: /* @__PURE__ */ C("a", {
|
|
198
|
+
href: N.website,
|
|
203
199
|
target: "_blank",
|
|
204
200
|
rel: "noreferrer",
|
|
205
201
|
className: "text-[var(--color-action-primary-bg)] underline-offset-2 hover:underline",
|
|
206
|
-
children:
|
|
202
|
+
children: N.website
|
|
207
203
|
})
|
|
208
204
|
})]
|
|
209
205
|
}) : null,
|
|
210
|
-
|
|
206
|
+
N.description ? /* @__PURE__ */ w("div", {
|
|
211
207
|
className: "sm:col-span-2",
|
|
212
|
-
children: [/* @__PURE__ */
|
|
208
|
+
children: [/* @__PURE__ */ C("dt", {
|
|
213
209
|
className: "text-sm font-medium text-[var(--color-text-secondary)]",
|
|
214
|
-
children:
|
|
215
|
-
}), /* @__PURE__ */
|
|
210
|
+
children: D("common.description", "Description")
|
|
211
|
+
}), /* @__PURE__ */ C("dd", {
|
|
216
212
|
className: "mt-1 text-sm leading-6 text-[var(--color-text-primary)]",
|
|
217
|
-
children:
|
|
213
|
+
children: N.description
|
|
218
214
|
})]
|
|
219
215
|
}) : null
|
|
220
216
|
]
|
|
221
217
|
})]
|
|
222
|
-
}), /* @__PURE__ */ x
|
|
223
|
-
|
|
224
|
-
|
|
218
|
+
}), /* @__PURE__ */ w(x, {
|
|
219
|
+
treatment: "plain",
|
|
220
|
+
className: "border-border-seam bg-[var(--color-bg-canvas)] p-5 xl:sticky xl:top-6 xl:self-start",
|
|
221
|
+
children: [/* @__PURE__ */ C("h2", {
|
|
225
222
|
className: "text-lg font-semibold text-[var(--color-text-primary)]",
|
|
226
|
-
children:
|
|
227
|
-
}), /* @__PURE__ */
|
|
223
|
+
children: D("common.metadata", "Metadata")
|
|
224
|
+
}), /* @__PURE__ */ w("dl", {
|
|
228
225
|
className: "mt-5 space-y-4",
|
|
229
226
|
children: [
|
|
230
|
-
/* @__PURE__ */
|
|
227
|
+
/* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("dt", {
|
|
231
228
|
className: "text-sm font-medium text-[var(--color-text-secondary)]",
|
|
232
|
-
children:
|
|
233
|
-
}), /* @__PURE__ */
|
|
229
|
+
children: D("common.created", "Created")
|
|
230
|
+
}), /* @__PURE__ */ C("dd", {
|
|
234
231
|
className: "mt-1 text-sm text-[var(--color-text-primary)]",
|
|
235
|
-
children:
|
|
232
|
+
children: E(N.createdAt)
|
|
236
233
|
})] }),
|
|
237
|
-
/* @__PURE__ */
|
|
234
|
+
/* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("dt", {
|
|
238
235
|
className: "text-sm font-medium text-[var(--color-text-secondary)]",
|
|
239
|
-
children:
|
|
240
|
-
}), /* @__PURE__ */
|
|
236
|
+
children: D("common.lastUpdated", "Last updated")
|
|
237
|
+
}), /* @__PURE__ */ C("dd", {
|
|
241
238
|
className: "mt-1 text-sm text-[var(--color-text-primary)]",
|
|
242
|
-
children:
|
|
239
|
+
children: E(N.updatedAt)
|
|
243
240
|
})] }),
|
|
244
|
-
/* @__PURE__ */
|
|
241
|
+
/* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("dt", {
|
|
245
242
|
className: "text-sm font-medium text-[var(--color-text-secondary)]",
|
|
246
|
-
children:
|
|
247
|
-
}), /* @__PURE__ */
|
|
243
|
+
children: D("organizations.detail.tenantId", "Tenant ID")
|
|
244
|
+
}), /* @__PURE__ */ C("dd", {
|
|
248
245
|
className: "mt-1 break-all font-mono text-sm text-[var(--color-text-primary)]",
|
|
249
|
-
children:
|
|
246
|
+
children: N.tenantId
|
|
250
247
|
})] })
|
|
251
248
|
]
|
|
252
249
|
})]
|
|
253
250
|
})]
|
|
254
|
-
}) : /* @__PURE__ */
|
|
251
|
+
}) : /* @__PURE__ */ w("section", {
|
|
255
252
|
className: "space-y-4",
|
|
256
|
-
children: [/* @__PURE__ */
|
|
253
|
+
children: [/* @__PURE__ */ w("div", {
|
|
257
254
|
className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",
|
|
258
|
-
children: [/* @__PURE__ */
|
|
255
|
+
children: [/* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("h2", {
|
|
259
256
|
className: "text-lg font-semibold text-[var(--color-text-primary)]",
|
|
260
|
-
children:
|
|
261
|
-
}), /* @__PURE__ */
|
|
257
|
+
children: D("organizations.detail.workspacesTitle", "Organization workspaces")
|
|
258
|
+
}), /* @__PURE__ */ C("p", {
|
|
262
259
|
className: "text-sm text-[var(--color-text-secondary)]",
|
|
263
|
-
children:
|
|
264
|
-
})] }),
|
|
260
|
+
children: D("organizations.detail.workspacesSubtitle", "Create and manage workspaces for this organization.")
|
|
261
|
+
})] }), j(s.WORKSPACE_CREATE) && /* @__PURE__ */ w("button", {
|
|
265
262
|
type: "button",
|
|
266
|
-
onClick: () =>
|
|
263
|
+
onClick: () => k(`${A}/workspaces/new?organizationId=${O}`),
|
|
267
264
|
className: "inline-flex min-h-11 items-center justify-center gap-2 rounded-lg bg-[var(--color-action-primary-bg)] px-4 py-2.5 text-[var(--color-action-primary-text)] transition-all duration-200 hover:opacity-90",
|
|
268
|
-
children: [/* @__PURE__ */
|
|
265
|
+
children: [/* @__PURE__ */ C(m, {
|
|
269
266
|
size: 16,
|
|
270
267
|
"aria-hidden": "true"
|
|
271
|
-
}), /* @__PURE__ */
|
|
268
|
+
}), /* @__PURE__ */ C("span", { children: D("workspaces.create.button", "Create Workspace") })]
|
|
272
269
|
})]
|
|
273
|
-
}),
|
|
270
|
+
}), z ? /* @__PURE__ */ C("div", {
|
|
274
271
|
className: "py-8",
|
|
275
|
-
children: /* @__PURE__ */
|
|
276
|
-
}) :
|
|
277
|
-
message:
|
|
272
|
+
children: /* @__PURE__ */ C(i, { message: D("workspaces.list.loading", "Loading workspaces...") })
|
|
273
|
+
}) : B ? /* @__PURE__ */ C(a, {
|
|
274
|
+
message: B.message,
|
|
278
275
|
action: {
|
|
279
|
-
label:
|
|
276
|
+
label: D("common.retry", "Retry"),
|
|
280
277
|
onClick: () => {
|
|
281
|
-
|
|
278
|
+
V();
|
|
282
279
|
}
|
|
283
280
|
}
|
|
284
|
-
}) :
|
|
281
|
+
}) : R.length > 0 ? /* @__PURE__ */ C("div", {
|
|
285
282
|
className: "grid grid-cols-1 gap-4 xl:grid-cols-2",
|
|
286
|
-
children:
|
|
283
|
+
children: R.map((e) => /* @__PURE__ */ C(u, {
|
|
287
284
|
workspace: e,
|
|
288
285
|
showActions: !1,
|
|
289
286
|
onClick: (e) => {
|
|
290
|
-
|
|
287
|
+
k(`${A}/workspaces/${e.id}`);
|
|
291
288
|
}
|
|
292
289
|
}, e.id))
|
|
293
|
-
}) : /* @__PURE__ */
|
|
290
|
+
}) : /* @__PURE__ */ C("div", {
|
|
294
291
|
className: "rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-canvas)] p-6",
|
|
295
|
-
children: /* @__PURE__ */
|
|
296
|
-
icon: /* @__PURE__ */
|
|
292
|
+
children: /* @__PURE__ */ C(o, {
|
|
293
|
+
icon: /* @__PURE__ */ C(m, {
|
|
297
294
|
size: 40,
|
|
298
295
|
"aria-hidden": "true"
|
|
299
296
|
}),
|
|
300
|
-
title:
|
|
301
|
-
description:
|
|
302
|
-
action:
|
|
303
|
-
label:
|
|
304
|
-
onClick: () =>
|
|
297
|
+
title: D("workspaces.list.emptyTitle", "No workspaces yet"),
|
|
298
|
+
description: j(s.WORKSPACE_CREATE) ? D("workspaces.list.emptyDescription", "Create a workspace when this organization is ready to collaborate with teams or projects.") : D("workspaces.list.emptyDescriptionViewer", "No workspaces have been created in this organization yet."),
|
|
299
|
+
action: j(s.WORKSPACE_CREATE) ? {
|
|
300
|
+
label: D("workspaces.create.button", "Create Workspace"),
|
|
301
|
+
onClick: () => k(`${A}/workspaces/new?organizationId=${O}`)
|
|
305
302
|
} : void 0
|
|
306
303
|
})
|
|
307
304
|
})]
|
|
@@ -309,15 +306,15 @@ function w() {
|
|
|
309
306
|
})]
|
|
310
307
|
})]
|
|
311
308
|
})
|
|
312
|
-
}) : /* @__PURE__ */
|
|
309
|
+
}) : /* @__PURE__ */ C("div", {
|
|
313
310
|
className: "min-h-full bg-[var(--color-bg-canvas)] p-6",
|
|
314
|
-
children: /* @__PURE__ */
|
|
311
|
+
children: /* @__PURE__ */ C("div", {
|
|
315
312
|
className: "p-8 text-center text-[var(--color-text-secondary)]",
|
|
316
|
-
children:
|
|
313
|
+
children: D("organizations.detail.noPermission", "You don't have permission to view this organization.")
|
|
317
314
|
})
|
|
318
315
|
});
|
|
319
316
|
}
|
|
320
317
|
//#endregion
|
|
321
|
-
export {
|
|
318
|
+
export { D as OrganizationDetailPage };
|
|
322
319
|
|
|
323
320
|
//# sourceMappingURL=OrganizationDetailPage.js.map
|
package/dist/organization-management/modules/organizations/pages/OrganizationDetailPage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OrganizationDetailPage.js","names":[],"sources":["../../../../../src/organization-management/modules/organizations/pages/OrganizationDetailPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { ArrowLeft, Briefcase, Building, Edit, UserPlus, Users } from 'lucide-react';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useOrgConsole } from '../../../providers/OrgConsoleProvider';\nimport { useOrganization } from '../hooks/useOrganizations';\nimport { OrganizationStatusBadge } from '../components/OrganizationStatusBadge';\nimport { LoadingState } from '../../../shared/components/feedback/LoadingState';\nimport { ErrorState } from '../../../shared/components/feedback/ErrorState';\nimport { EmptyState } from '../../../shared/components/feedback/EmptyState';\nimport { useWorkspacesByOrganization } from '../../workspaces/hooks/useWorkspaces';\nimport { WorkspaceCard } from '../../workspaces/components/WorkspaceCard';\nimport { PERMISSIONS } from '../../../constants/permissions';\nimport { useTr } from '../../../shared/hooks/useTr';\nimport { useOrganizationPageView } from '../../../hooks/useOrganizationPageView';\n\ntype ActiveTab = 'overview' | 'workspaces';\n\nfunction formatDate(dateString: string) {\n return new Date(dateString).toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n}\n\nexport function OrganizationDetailPage() {\n const tr = useTr();\n const { id } = useParams<{ id: string }>();\n useOrganizationPageView('organizations.detail', { organizationId: id });\n const { navigate, basePath = '/organizations' } = useOrgConsole();\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n const { organization, loading, error } = useOrganization(id ?? '');\n const [activeTab, setActiveTab] = useState<ActiveTab>('overview');\n\n const shouldFetchWorkspaces = activeTab === 'workspaces' && Boolean(id);\n const {\n workspaces,\n loading: workspacesLoading,\n error: workspacesError,\n refetch: refetchWorkspaces,\n } = useWorkspacesByOrganization(shouldFetchWorkspaces ? (id ?? '') : '', 50, 0);\n\n const tabItems = useMemo(\n () => [\n { id: 'overview' as const, label: tr('organizations.detail.tab.overview', 'Overview') },\n {\n id: 'workspaces' as const,\n label: `${tr('organizations.detail.tab.workspaces', 'Workspaces')} (${activeTab === 'workspaces' ? workspaces.length : (organization?.workspaceCount ?? 0)})`,\n },\n ],\n [activeTab, organization?.workspaceCount, tr, workspaces.length]\n );\n\n if (permissionsLoading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <LoadingState message={tr('common.loadingPermissions', 'Loading permissions...')} />\n </div>\n );\n }\n\n if (!hasPermission(PERMISSIONS.ORG_READ)) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <div className=\"p-8 text-center text-[var(--color-text-secondary)]\">\n {tr(\n 'organizations.detail.noPermission',\n \"You don't have permission to view this organization.\"\n )}\n </div>\n </div>\n );\n }\n\n if (loading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <LoadingState\n message={tr('organizations.detail.loading', 'Loading organization details...')}\n />\n </div>\n );\n }\n\n if (error || !organization) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <ErrorState\n message={error?.message || tr('organizations.detail.notFound', 'Organization not found')}\n action={{\n label: tr('organizations.create.back', 'Back to Organizations'),\n onClick: () => navigate(basePath),\n }}\n />\n </div>\n );\n }\n\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6 animate-in fade-in duration-200\">\n <div className=\"mx-auto flex w-full max-w-7xl flex-col gap-6\">\n <div className=\"space-y-4\">\n <button\n type=\"button\"\n onClick={() => navigate(basePath)}\n className=\"inline-flex min-h-10 items-center gap-2 text-[var(--color-text-secondary)] transition-all duration-200 hover:text-[var(--color-text-primary)]\"\n >\n <ArrowLeft size={20} aria-hidden=\"true\" />\n <span className=\"text-sm font-medium\">\n {tr('organizations.create.back', 'Back to Organizations')}\n </span>\n </button>\n\n <div className=\"flex flex-col gap-4 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] p-5 shadow-[var(--shadow-elevation-1)] lg:flex-row lg:items-start lg:justify-between\">\n <div className=\"flex min-w-0 items-start gap-4\">\n <div className=\"flex size-16 items-center justify-center rounded-xl bg-[var(--color-status-info-bgSubtle)] text-[var(--color-status-info-text)]\">\n <Building size={28} aria-hidden=\"true\" />\n </div>\n\n <div className=\"min-w-0 space-y-2\">\n <div className=\"flex flex-wrap items-start gap-3\">\n <h1 className=\"text-3xl font-bold text-[var(--color-text-primary)]\">\n {organization.name}\n </h1>\n <OrganizationStatusBadge status={organization.status} />\n </div>\n <p className=\"break-all font-mono text-sm text-[var(--color-text-secondary)]\">\n /{organization.slug}\n </p>\n {organization.description ? (\n <p className=\"max-w-2xl text-sm text-[var(--color-text-secondary)]\">\n {organization.description}\n </p>\n ) : null}\n </div>\n </div>\n\n <div className=\"flex flex-col gap-3 sm:flex-row\">\n {hasPermission(PERMISSIONS.MEMBER_LIST) && (\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/${id}/members`)}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg border border-[var(--color-border-default)] px-4 py-2.5 text-[var(--color-text-primary)] transition-all duration-200 hover:bg-[var(--color-bg-subtle)]\"\n >\n <Users size={16} aria-hidden=\"true\" />\n <span>\n {hasPermission(PERMISSIONS.MEMBER_INVITE)\n ? tr('organizations.detail.manageMembers', 'Manage Members')\n : tr('organizations.detail.viewMembers', 'View Members')}\n </span>\n </button>\n )}\n {hasPermission(PERMISSIONS.MEMBER_INVITE) && (\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/${id}/members/invite`)}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg border border-[var(--color-border-default)] px-4 py-2.5 text-[var(--color-text-primary)] transition-all duration-200 hover:bg-[var(--color-bg-subtle)]\"\n >\n <UserPlus size={16} aria-hidden=\"true\" />\n <span>{tr('members.invite.button', 'Invite Member')}</span>\n </button>\n )}\n {hasPermission(PERMISSIONS.ORG_UPDATE) && (\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/${id}/edit`)}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg bg-[var(--color-action-primary-bg)] px-4 py-2.5 text-[var(--color-action-primary-text)] transition-all duration-200 hover:opacity-90\"\n >\n <Edit size={16} aria-hidden=\"true\" />\n <span>{tr('organizations.edit.title', 'Edit Organization')}</span>\n </button>\n )}\n </div>\n </div>\n </div>\n\n <div className=\"rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] shadow-[var(--shadow-elevation-1)]\">\n <div className=\"overflow-x-auto border-b border-[var(--color-border-default)]\">\n <div className=\"flex min-w-max gap-2 px-4 pt-4 sm:px-6\">\n {tabItems.map((tabItem) => {\n const isActive = activeTab === tabItem.id;\n return (\n <button\n type=\"button\"\n key={tabItem.id}\n onClick={() => setActiveTab(tabItem.id)}\n className={`inline-flex min-h-11 items-center rounded-t-lg border-b-2 px-4 py-3 text-sm font-medium transition-colors ${\n isActive\n ? 'border-[var(--color-action-primary-bg)] text-[var(--color-action-primary-bg)]'\n : 'border-transparent text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)]'\n }`}\n aria-pressed={isActive}\n >\n {tabItem.label}\n </button>\n );\n })}\n </div>\n </div>\n\n <div className=\"p-4 sm:p-6\">\n {activeTab === 'overview' ? (\n <div className=\"grid grid-cols-1 gap-6 xl:grid-cols-[minmax(0,1fr)_320px]\">\n <section className=\"rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-canvas)] p-5\">\n <h2 className=\"text-lg font-semibold text-[var(--color-text-primary)]\">\n {tr('organizations.detail.detailsSection', 'Organization details')}\n </h2>\n\n <dl className=\"mt-5 grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('common.name', 'Name')}\n </dt>\n <dd className=\"mt-1 text-sm text-[var(--color-text-primary)]\">\n {organization.name}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('common.slug', 'Slug')}\n </dt>\n <dd className=\"mt-1 break-all font-mono text-sm text-[var(--color-text-primary)]\">\n {organization.slug}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('common.status', 'Status')}\n </dt>\n <dd className=\"mt-1\">\n <OrganizationStatusBadge status={organization.status} />\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('organizations.detail.workspaceCount', 'Workspace count')}\n </dt>\n <dd className=\"mt-1 text-sm text-[var(--color-text-primary)]\">\n {organization.workspaceCount ?? 0}\n </dd>\n </div>\n {organization.website ? (\n <div className=\"sm:col-span-2\">\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('organizations.detail.website', 'Website')}\n </dt>\n <dd className=\"mt-1 break-all text-sm\">\n <a\n href={organization.website}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"text-[var(--color-action-primary-bg)] underline-offset-2 hover:underline\"\n >\n {organization.website}\n </a>\n </dd>\n </div>\n ) : null}\n {organization.description ? (\n <div className=\"sm:col-span-2\">\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('common.description', 'Description')}\n </dt>\n <dd className=\"mt-1 text-sm leading-6 text-[var(--color-text-primary)]\">\n {organization.description}\n </dd>\n </div>\n ) : null}\n </dl>\n </section>\n\n <aside className=\"rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-canvas)] p-5\">\n <h2 className=\"text-lg font-semibold text-[var(--color-text-primary)]\">\n {tr('common.metadata', 'Metadata')}\n </h2>\n\n <dl className=\"mt-5 space-y-4\">\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('common.created', 'Created')}\n </dt>\n <dd className=\"mt-1 text-sm text-[var(--color-text-primary)]\">\n {formatDate(organization.createdAt)}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('common.lastUpdated', 'Last updated')}\n </dt>\n <dd className=\"mt-1 text-sm text-[var(--color-text-primary)]\">\n {formatDate(organization.updatedAt)}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('organizations.detail.tenantId', 'Tenant ID')}\n </dt>\n <dd className=\"mt-1 break-all font-mono text-sm text-[var(--color-text-primary)]\">\n {organization.tenantId}\n </dd>\n </div>\n </dl>\n </aside>\n </div>\n ) : (\n <section className=\"space-y-4\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h2 className=\"text-lg font-semibold text-[var(--color-text-primary)]\">\n {tr('organizations.detail.workspacesTitle', 'Organization workspaces')}\n </h2>\n <p className=\"text-sm text-[var(--color-text-secondary)]\">\n {tr(\n 'organizations.detail.workspacesSubtitle',\n 'Create and manage workspaces for this organization.'\n )}\n </p>\n </div>\n\n {hasPermission(PERMISSIONS.WORKSPACE_CREATE) && (\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/workspaces/new?organizationId=${id}`)}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg bg-[var(--color-action-primary-bg)] px-4 py-2.5 text-[var(--color-action-primary-text)] transition-all duration-200 hover:opacity-90\"\n >\n <Briefcase size={16} aria-hidden=\"true\" />\n <span>{tr('workspaces.create.button', 'Create Workspace')}</span>\n </button>\n )}\n </div>\n\n {workspacesLoading ? (\n <div className=\"py-8\">\n <LoadingState\n message={tr('workspaces.list.loading', 'Loading workspaces...')}\n />\n </div>\n ) : workspacesError ? (\n <ErrorState\n message={workspacesError.message}\n action={{\n label: tr('common.retry', 'Retry'),\n onClick: () => {\n void refetchWorkspaces();\n },\n }}\n />\n ) : workspaces.length > 0 ? (\n <div className=\"grid grid-cols-1 gap-4 xl:grid-cols-2\">\n {workspaces.map((workspace) => (\n <WorkspaceCard\n key={workspace.id}\n workspace={workspace}\n showActions={false}\n onClick={(selectedWorkspace) => {\n navigate(`${basePath}/workspaces/${selectedWorkspace.id}`);\n }}\n />\n ))}\n </div>\n ) : (\n <div className=\"rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-canvas)] p-6\">\n <EmptyState\n icon={<Briefcase size={40} aria-hidden=\"true\" />}\n title={tr('workspaces.list.emptyTitle', 'No workspaces yet')}\n description={\n hasPermission(PERMISSIONS.WORKSPACE_CREATE)\n ? tr(\n 'workspaces.list.emptyDescription',\n 'Create a workspace when this organization is ready to collaborate with teams or projects.'\n )\n : tr(\n 'workspaces.list.emptyDescriptionViewer',\n 'No workspaces have been created in this organization yet.'\n )\n }\n action={\n hasPermission(PERMISSIONS.WORKSPACE_CREATE)\n ? {\n label: tr('workspaces.create.button', 'Create Workspace'),\n onClick: () =>\n navigate(`${basePath}/workspaces/new?organizationId=${id}`),\n }\n : undefined\n }\n />\n </div>\n )}\n </section>\n )}\n </div>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"OrganizationDetailPage.js","names":[],"sources":["../../../../../src/organization-management/modules/organizations/pages/OrganizationDetailPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { ArrowLeft, Briefcase, Building, Edit, UserPlus, Users } from 'lucide-react';\nimport { CTAOverflowMenu, EmphasisPanel, GlassCard } from '@burdenoff/fe-libs/ui';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useOrgConsole } from '../../../providers/OrgConsoleProvider';\nimport { useOrganization } from '../hooks/useOrganizations';\nimport { OrganizationStatusBadge } from '../components/OrganizationStatusBadge';\nimport { LoadingState } from '../../../shared/components/feedback/LoadingState';\nimport { ErrorState } from '../../../shared/components/feedback/ErrorState';\nimport { EmptyState } from '../../../shared/components/feedback/EmptyState';\nimport { useWorkspacesByOrganization } from '../../workspaces/hooks/useWorkspaces';\nimport { WorkspaceCard } from '../../workspaces/components/WorkspaceCard';\nimport { PERMISSIONS } from '../../../constants/permissions';\nimport { useTr } from '../../../shared/hooks/useTr';\nimport { useOrganizationPageView } from '../../../hooks/useOrganizationPageView';\n\ntype ActiveTab = 'overview' | 'workspaces';\n\nfunction formatDate(dateString: string) {\n return new Date(dateString).toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n}\n\nexport function OrganizationDetailPage() {\n const tr = useTr();\n const { id } = useParams<{ id: string }>();\n useOrganizationPageView('organizations.detail', { organizationId: id });\n const { navigate, basePath = '/organizations' } = useOrgConsole();\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n const { organization, loading, error } = useOrganization(id ?? '');\n const [activeTab, setActiveTab] = useState<ActiveTab>('overview');\n\n const shouldFetchWorkspaces = activeTab === 'workspaces' && Boolean(id);\n const {\n workspaces,\n loading: workspacesLoading,\n error: workspacesError,\n refetch: refetchWorkspaces,\n } = useWorkspacesByOrganization(shouldFetchWorkspaces ? (id ?? '') : '', 50, 0);\n\n const tabItems = useMemo(\n () => [\n { id: 'overview' as const, label: tr('organizations.detail.tab.overview', 'Overview') },\n {\n id: 'workspaces' as const,\n label: `${tr('organizations.detail.tab.workspaces', 'Workspaces')} (${activeTab === 'workspaces' ? workspaces.length : (organization?.workspaceCount ?? 0)})`,\n },\n ],\n [activeTab, organization?.workspaceCount, tr, workspaces.length]\n );\n\n if (permissionsLoading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <LoadingState message={tr('common.loadingPermissions', 'Loading permissions...')} />\n </div>\n );\n }\n\n if (!hasPermission(PERMISSIONS.ORG_READ)) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <div className=\"p-8 text-center text-[var(--color-text-secondary)]\">\n {tr(\n 'organizations.detail.noPermission',\n \"You don't have permission to view this organization.\"\n )}\n </div>\n </div>\n );\n }\n\n if (loading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <LoadingState\n message={tr('organizations.detail.loading', 'Loading organization details...')}\n />\n </div>\n );\n }\n\n if (error || !organization) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <ErrorState\n message={error?.message || tr('organizations.detail.notFound', 'Organization not found')}\n action={{\n label: tr('organizations.create.back', 'Back to Organizations'),\n onClick: () => navigate(basePath),\n }}\n />\n </div>\n );\n }\n\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6 animate-in fade-in duration-200\">\n <div className=\"mx-auto flex w-full max-w-7xl flex-col gap-6\">\n <div className=\"space-y-4\">\n <button\n type=\"button\"\n onClick={() => navigate(basePath)}\n className=\"inline-flex min-h-10 items-center gap-2 text-[var(--color-text-secondary)] transition-all duration-200 hover:text-[var(--color-text-primary)]\"\n >\n <ArrowLeft size={20} aria-hidden=\"true\" />\n <span className=\"text-sm font-medium\">\n {tr('organizations.create.back', 'Back to Organizations')}\n </span>\n </button>\n\n <EmphasisPanel className=\"flex flex-col gap-4 p-5 lg:flex-row lg:items-start lg:justify-between\">\n <div className=\"flex min-w-0 items-start gap-4\">\n <div className=\"flex size-16 items-center justify-center rounded-xl bg-[var(--color-status-info-bgSubtle)] text-[var(--color-status-info-text)]\">\n <Building size={28} aria-hidden=\"true\" />\n </div>\n\n <div className=\"min-w-0 space-y-2\">\n <div className=\"flex flex-wrap items-start gap-3\">\n <h1 className=\"text-3xl font-bold text-[var(--color-text-primary)]\">\n {organization.name}\n </h1>\n <OrganizationStatusBadge status={organization.status} />\n </div>\n <p className=\"break-all font-mono text-sm text-[var(--color-text-secondary)]\">\n /{organization.slug}\n </p>\n {organization.description ? (\n <p className=\"max-w-2xl text-sm text-[var(--color-text-secondary)]\">\n {organization.description}\n </p>\n ) : null}\n </div>\n </div>\n\n <CTAOverflowMenu\n primary={\n hasPermission(PERMISSIONS.ORG_UPDATE)\n ? {\n label: tr('organizations.edit.title', 'Edit Organization'),\n icon: <Edit size={16} aria-hidden=\"true\" />,\n onSelect: () => navigate(`${basePath}/${id}/edit`),\n }\n : undefined\n }\n actions={[\n ...(hasPermission(PERMISSIONS.MEMBER_LIST)\n ? [\n {\n label: hasPermission(PERMISSIONS.MEMBER_INVITE)\n ? tr('organizations.detail.manageMembers', 'Manage Members')\n : tr('organizations.detail.viewMembers', 'View Members'),\n icon: <Users size={16} aria-hidden=\"true\" />,\n onSelect: () => navigate(`${basePath}/${id}/members`),\n },\n ]\n : []),\n ...(hasPermission(PERMISSIONS.MEMBER_INVITE)\n ? [\n {\n label: tr('members.invite.button', 'Invite Member'),\n icon: <UserPlus size={16} aria-hidden=\"true\" />,\n onSelect: () => navigate(`${basePath}/${id}/members/invite`),\n },\n ]\n : []),\n ]}\n />\n </EmphasisPanel>\n </div>\n\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-0\">\n <div className=\"overflow-x-auto border-b border-[var(--color-border-seam)]\">\n <div className=\"flex min-w-max gap-2 px-4 pt-4 sm:px-6\">\n {tabItems.map((tabItem) => {\n const isActive = activeTab === tabItem.id;\n return (\n <button\n type=\"button\"\n key={tabItem.id}\n onClick={() => setActiveTab(tabItem.id)}\n className={`inline-flex min-h-11 items-center rounded-t-lg border-b-2 px-4 py-3 text-sm font-medium transition-colors ${\n isActive\n ? 'border-[var(--color-action-primary-bg)] text-[var(--color-action-primary-bg)]'\n : 'border-transparent text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)]'\n }`}\n aria-pressed={isActive}\n >\n {tabItem.label}\n </button>\n );\n })}\n </div>\n </div>\n\n <div className=\"p-4 sm:p-6\">\n {activeTab === 'overview' ? (\n <div className=\"grid grid-cols-1 gap-6 xl:grid-cols-[minmax(0,1fr)_320px]\">\n <GlassCard\n treatment=\"plain\"\n className=\"border-border-seam bg-[var(--color-bg-canvas)] p-5\"\n >\n <h2 className=\"text-lg font-semibold text-[var(--color-text-primary)]\">\n {tr('organizations.detail.detailsSection', 'Organization details')}\n </h2>\n\n <dl className=\"mt-5 grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('common.name', 'Name')}\n </dt>\n <dd className=\"mt-1 text-sm text-[var(--color-text-primary)]\">\n {organization.name}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('common.slug', 'Slug')}\n </dt>\n <dd className=\"mt-1 break-all font-mono text-sm text-[var(--color-text-primary)]\">\n {organization.slug}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('common.status', 'Status')}\n </dt>\n <dd className=\"mt-1\">\n <OrganizationStatusBadge status={organization.status} />\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('organizations.detail.workspaceCount', 'Workspace count')}\n </dt>\n <dd className=\"mt-1 text-sm text-[var(--color-text-primary)]\">\n {organization.workspaceCount ?? 0}\n </dd>\n </div>\n {organization.website ? (\n <div className=\"sm:col-span-2\">\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('organizations.detail.website', 'Website')}\n </dt>\n <dd className=\"mt-1 break-all text-sm\">\n <a\n href={organization.website}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"text-[var(--color-action-primary-bg)] underline-offset-2 hover:underline\"\n >\n {organization.website}\n </a>\n </dd>\n </div>\n ) : null}\n {organization.description ? (\n <div className=\"sm:col-span-2\">\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('common.description', 'Description')}\n </dt>\n <dd className=\"mt-1 text-sm leading-6 text-[var(--color-text-primary)]\">\n {organization.description}\n </dd>\n </div>\n ) : null}\n </dl>\n </GlassCard>\n\n <GlassCard\n treatment=\"plain\"\n className=\"border-border-seam bg-[var(--color-bg-canvas)] p-5 xl:sticky xl:top-6 xl:self-start\"\n >\n <h2 className=\"text-lg font-semibold text-[var(--color-text-primary)]\">\n {tr('common.metadata', 'Metadata')}\n </h2>\n\n <dl className=\"mt-5 space-y-4\">\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('common.created', 'Created')}\n </dt>\n <dd className=\"mt-1 text-sm text-[var(--color-text-primary)]\">\n {formatDate(organization.createdAt)}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('common.lastUpdated', 'Last updated')}\n </dt>\n <dd className=\"mt-1 text-sm text-[var(--color-text-primary)]\">\n {formatDate(organization.updatedAt)}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-[var(--color-text-secondary)]\">\n {tr('organizations.detail.tenantId', 'Tenant ID')}\n </dt>\n <dd className=\"mt-1 break-all font-mono text-sm text-[var(--color-text-primary)]\">\n {organization.tenantId}\n </dd>\n </div>\n </dl>\n </GlassCard>\n </div>\n ) : (\n <section className=\"space-y-4\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h2 className=\"text-lg font-semibold text-[var(--color-text-primary)]\">\n {tr('organizations.detail.workspacesTitle', 'Organization workspaces')}\n </h2>\n <p className=\"text-sm text-[var(--color-text-secondary)]\">\n {tr(\n 'organizations.detail.workspacesSubtitle',\n 'Create and manage workspaces for this organization.'\n )}\n </p>\n </div>\n\n {hasPermission(PERMISSIONS.WORKSPACE_CREATE) && (\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/workspaces/new?organizationId=${id}`)}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg bg-[var(--color-action-primary-bg)] px-4 py-2.5 text-[var(--color-action-primary-text)] transition-all duration-200 hover:opacity-90\"\n >\n <Briefcase size={16} aria-hidden=\"true\" />\n <span>{tr('workspaces.create.button', 'Create Workspace')}</span>\n </button>\n )}\n </div>\n\n {workspacesLoading ? (\n <div className=\"py-8\">\n <LoadingState\n message={tr('workspaces.list.loading', 'Loading workspaces...')}\n />\n </div>\n ) : workspacesError ? (\n <ErrorState\n message={workspacesError.message}\n action={{\n label: tr('common.retry', 'Retry'),\n onClick: () => {\n void refetchWorkspaces();\n },\n }}\n />\n ) : workspaces.length > 0 ? (\n <div className=\"grid grid-cols-1 gap-4 xl:grid-cols-2\">\n {workspaces.map((workspace) => (\n <WorkspaceCard\n key={workspace.id}\n workspace={workspace}\n showActions={false}\n onClick={(selectedWorkspace) => {\n navigate(`${basePath}/workspaces/${selectedWorkspace.id}`);\n }}\n />\n ))}\n </div>\n ) : (\n <div className=\"rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-canvas)] p-6\">\n <EmptyState\n icon={<Briefcase size={40} aria-hidden=\"true\" />}\n title={tr('workspaces.list.emptyTitle', 'No workspaces yet')}\n description={\n hasPermission(PERMISSIONS.WORKSPACE_CREATE)\n ? tr(\n 'workspaces.list.emptyDescription',\n 'Create a workspace when this organization is ready to collaborate with teams or projects.'\n )\n : tr(\n 'workspaces.list.emptyDescriptionViewer',\n 'No workspaces have been created in this organization yet.'\n )\n }\n action={\n hasPermission(PERMISSIONS.WORKSPACE_CREATE)\n ? {\n label: tr('workspaces.create.button', 'Create Workspace'),\n onClick: () =>\n navigate(`${basePath}/workspaces/new?organizationId=${id}`),\n }\n : undefined\n }\n />\n </div>\n )}\n </section>\n )}\n </div>\n </GlassCard>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|