@mdxui/auth 1.1.1 → 1.4.0
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/{auth-Ba2f778e.d.ts → auth-maeYSYU_.d.ts} +4 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/{index-DGthQxCM.d.ts → index-BOMpMKyG.d.ts} +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +794 -4
- package/dist/index.js.map +1 -1
- package/dist/providers/index.d.ts +2 -2
- package/dist/providers/index.js +16 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/schemas/index.d.ts +5 -0
- package/dist/schemas/index.js +1 -1
- package/dist/schemas/index.js.map +1 -1
- package/dist/shell/index.d.ts +675 -0
- package/dist/shell/index.js +1025 -0
- package/dist/shell/index.js.map +1 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/widgets/index.d.ts +1 -1
- package/package.json +21 -14
|
@@ -0,0 +1,1025 @@
|
|
|
1
|
+
// src/shell/config-context.tsx
|
|
2
|
+
import { createContext, useContext, useMemo } from "react";
|
|
3
|
+
|
|
4
|
+
// src/shell/route-presets.ts
|
|
5
|
+
import { Key, Monitor, Plug, Shield, User, Users } from "lucide-react";
|
|
6
|
+
|
|
7
|
+
// src/widgets/user-profile.tsx
|
|
8
|
+
import { UserProfile as WorkOSUserProfile } from "@workos-inc/widgets";
|
|
9
|
+
import { jsx } from "react/jsx-runtime";
|
|
10
|
+
function UserProfile({ authToken, className }) {
|
|
11
|
+
return /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsx(WorkOSUserProfile, { authToken }) });
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// src/hooks/use-auth.ts
|
|
15
|
+
import { useAuth } from "@workos-inc/authkit-react";
|
|
16
|
+
|
|
17
|
+
// src/shell/components/breadcrumbs.tsx
|
|
18
|
+
import { WebLink } from "@mdxui/navigation/web";
|
|
19
|
+
import {
|
|
20
|
+
Breadcrumb,
|
|
21
|
+
BreadcrumbEllipsis,
|
|
22
|
+
BreadcrumbItem,
|
|
23
|
+
BreadcrumbLink,
|
|
24
|
+
BreadcrumbList,
|
|
25
|
+
BreadcrumbPage,
|
|
26
|
+
BreadcrumbSeparator
|
|
27
|
+
} from "@mdxui/primitives/breadcrumb";
|
|
28
|
+
import {
|
|
29
|
+
DropdownMenu,
|
|
30
|
+
DropdownMenuContent,
|
|
31
|
+
DropdownMenuItem,
|
|
32
|
+
DropdownMenuTrigger
|
|
33
|
+
} from "@mdxui/primitives/dropdown-menu";
|
|
34
|
+
import * as React from "react";
|
|
35
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
36
|
+
function DefaultLink({ href, children, className }) {
|
|
37
|
+
return /* @__PURE__ */ jsx2(WebLink, { to: href, className, children });
|
|
38
|
+
}
|
|
39
|
+
function Breadcrumbs({
|
|
40
|
+
items,
|
|
41
|
+
LinkComponent = DefaultLink,
|
|
42
|
+
className,
|
|
43
|
+
maxItems = 4,
|
|
44
|
+
separator
|
|
45
|
+
}) {
|
|
46
|
+
if (!items || items.length === 0) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
const shouldCollapse = items.length > maxItems;
|
|
50
|
+
const visibleItems = shouldCollapse ? [items[0], ...items.slice(-(maxItems - 1))] : items;
|
|
51
|
+
const hiddenItems = shouldCollapse ? items.slice(1, -(maxItems - 1)) : [];
|
|
52
|
+
return /* @__PURE__ */ jsx2(Breadcrumb, { className, children: /* @__PURE__ */ jsx2(BreadcrumbList, { children: visibleItems.map((item, index) => {
|
|
53
|
+
const isLast = index === visibleItems.length - 1;
|
|
54
|
+
const isFirst = index === 0;
|
|
55
|
+
if (shouldCollapse && isFirst) {
|
|
56
|
+
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
57
|
+
/* @__PURE__ */ jsx2(BreadcrumbItem, { children: item.href ? /* @__PURE__ */ jsx2(BreadcrumbLink, { asChild: true, children: /* @__PURE__ */ jsx2(LinkComponent, { href: item.href, children: item.label }) }) : /* @__PURE__ */ jsx2(BreadcrumbPage, { children: item.label }) }),
|
|
58
|
+
/* @__PURE__ */ jsx2(BreadcrumbSeparator, { children: separator }),
|
|
59
|
+
/* @__PURE__ */ jsx2(BreadcrumbItem, { children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
60
|
+
/* @__PURE__ */ jsx2(
|
|
61
|
+
DropdownMenuTrigger,
|
|
62
|
+
{
|
|
63
|
+
className: "flex items-center gap-1 hover:text-foreground",
|
|
64
|
+
"aria-label": "Show hidden breadcrumbs",
|
|
65
|
+
children: /* @__PURE__ */ jsx2(BreadcrumbEllipsis, { className: "size-4" })
|
|
66
|
+
}
|
|
67
|
+
),
|
|
68
|
+
/* @__PURE__ */ jsx2(DropdownMenuContent, { align: "start", children: hiddenItems.map((hiddenItem) => /* @__PURE__ */ jsx2(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsx2(LinkComponent, { href: hiddenItem.href || "#", children: hiddenItem.label }) }, hiddenItem.label)) })
|
|
69
|
+
] }) }),
|
|
70
|
+
/* @__PURE__ */ jsx2(BreadcrumbSeparator, { children: separator })
|
|
71
|
+
] }, item.label);
|
|
72
|
+
}
|
|
73
|
+
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
74
|
+
/* @__PURE__ */ jsx2(BreadcrumbItem, { children: isLast ? /* @__PURE__ */ jsx2(BreadcrumbPage, { children: item.label }) : item.href ? /* @__PURE__ */ jsx2(BreadcrumbLink, { asChild: true, children: /* @__PURE__ */ jsx2(LinkComponent, { href: item.href, children: item.label }) }) : /* @__PURE__ */ jsx2(BreadcrumbPage, { children: item.label }) }),
|
|
75
|
+
!isLast && /* @__PURE__ */ jsx2(BreadcrumbSeparator, { children: separator })
|
|
76
|
+
] }, item.label);
|
|
77
|
+
}) }) });
|
|
78
|
+
}
|
|
79
|
+
Breadcrumbs.displayName = "Breadcrumbs";
|
|
80
|
+
|
|
81
|
+
// src/components/team-switcher.tsx
|
|
82
|
+
import { useAuth as useAuth2 } from "@workos-inc/authkit-react";
|
|
83
|
+
import { OrganizationSwitcher } from "@workos-inc/widgets";
|
|
84
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
85
|
+
function TeamSwitcher({
|
|
86
|
+
renderWrapper,
|
|
87
|
+
renderNoOrganization,
|
|
88
|
+
className
|
|
89
|
+
}) {
|
|
90
|
+
const { getAccessToken, switchToOrganization, organizationId } = useAuth2();
|
|
91
|
+
if (!organizationId) {
|
|
92
|
+
return renderNoOrganization?.() ?? null;
|
|
93
|
+
}
|
|
94
|
+
const handleSwitchOrganization = ({
|
|
95
|
+
organizationId: organizationId2
|
|
96
|
+
}) => {
|
|
97
|
+
return switchToOrganization({ organizationId: organizationId2 });
|
|
98
|
+
};
|
|
99
|
+
const widget = /* @__PURE__ */ jsx3("div", { className: `organization-switcher-wrapper ${className ?? ""}`, children: /* @__PURE__ */ jsx3(
|
|
100
|
+
OrganizationSwitcher,
|
|
101
|
+
{
|
|
102
|
+
authToken: getAccessToken,
|
|
103
|
+
switchToOrganization: handleSwitchOrganization
|
|
104
|
+
}
|
|
105
|
+
) });
|
|
106
|
+
return renderWrapper ? renderWrapper(widget) : widget;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// src/shell/components/sidebar-org-switcher.tsx
|
|
110
|
+
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
111
|
+
function SidebarOrgSwitcher() {
|
|
112
|
+
const branding = useAuthShellBranding();
|
|
113
|
+
return /* @__PURE__ */ jsx4(
|
|
114
|
+
TeamSwitcher,
|
|
115
|
+
{
|
|
116
|
+
renderNoOrganization: () => /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 px-2", children: [
|
|
117
|
+
branding.logo && /* @__PURE__ */ jsx4("div", { className: "flex-shrink-0", children: branding.logo }),
|
|
118
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex flex-col gap-0.5 leading-none", children: [
|
|
119
|
+
/* @__PURE__ */ jsx4("span", { className: "font-semibold", children: branding.name }),
|
|
120
|
+
branding.tagline && /* @__PURE__ */ jsx4("span", { className: "text-xs text-muted-foreground", children: branding.tagline })
|
|
121
|
+
] })
|
|
122
|
+
] })
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// src/shell/components/widget-error-boundary.tsx
|
|
128
|
+
import { Component } from "react";
|
|
129
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
130
|
+
var widgetErrorMessages = {
|
|
131
|
+
profile: "Your profile is camera shy right now...",
|
|
132
|
+
security: "Security settings are being extra secure (maybe too secure)...",
|
|
133
|
+
sessions: "Your sessions are having a session of their own...",
|
|
134
|
+
"api-keys": "Your API keys are playing hide and seek...",
|
|
135
|
+
team: "Your team members wandered off for a moment...",
|
|
136
|
+
integrations: "Your integrations are having connection issues (ironic, we know)..."
|
|
137
|
+
};
|
|
138
|
+
var uppercaseWords = /* @__PURE__ */ new Set(["api", "sso", "mfa", "oauth", "jwt", "url", "id"]);
|
|
139
|
+
function formatWidgetName(widgetName) {
|
|
140
|
+
return widgetName.split("-").map((word) => {
|
|
141
|
+
const lower = word.toLowerCase();
|
|
142
|
+
if (uppercaseWords.has(lower)) {
|
|
143
|
+
return word.toUpperCase();
|
|
144
|
+
}
|
|
145
|
+
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
|
|
146
|
+
}).join(" ");
|
|
147
|
+
}
|
|
148
|
+
function getErrorMessage(widgetName) {
|
|
149
|
+
if (!widgetName) {
|
|
150
|
+
return "Something went wrong loading this widget.";
|
|
151
|
+
}
|
|
152
|
+
const knownMessage = widgetErrorMessages[widgetName];
|
|
153
|
+
if (knownMessage) {
|
|
154
|
+
return knownMessage;
|
|
155
|
+
}
|
|
156
|
+
return `Something went wrong loading your ${formatWidgetName(widgetName)}...`;
|
|
157
|
+
}
|
|
158
|
+
var WidgetErrorBoundary = class extends Component {
|
|
159
|
+
constructor(props) {
|
|
160
|
+
super(props);
|
|
161
|
+
this.state = { hasError: false };
|
|
162
|
+
}
|
|
163
|
+
static getDerivedStateFromError(error) {
|
|
164
|
+
return { hasError: true, error };
|
|
165
|
+
}
|
|
166
|
+
componentDidCatch(error, errorInfo) {
|
|
167
|
+
console.error("[WidgetErrorBoundary] Widget error:", error, errorInfo);
|
|
168
|
+
}
|
|
169
|
+
render() {
|
|
170
|
+
if (this.state.hasError) {
|
|
171
|
+
if (this.props.fallback) {
|
|
172
|
+
return this.props.fallback;
|
|
173
|
+
}
|
|
174
|
+
const message = getErrorMessage(this.props.widgetName);
|
|
175
|
+
return /* @__PURE__ */ jsxs3("div", { className: "flex flex-col items-center justify-center gap-2 rounded-[var(--radius-md)] border border-dashed py-12", children: [
|
|
176
|
+
/* @__PURE__ */ jsx5("p", { className: "text-muted-foreground text-sm", children: message }),
|
|
177
|
+
/* @__PURE__ */ jsx5("p", { className: "text-muted-foreground/60 text-xs", children: "Try refreshing the page." })
|
|
178
|
+
] });
|
|
179
|
+
}
|
|
180
|
+
return this.props.children;
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
// src/shell/pages/profile-page.tsx
|
|
185
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
186
|
+
function ProfilePage() {
|
|
187
|
+
const { user, getAccessToken, isLoading } = useAuth();
|
|
188
|
+
if (isLoading) {
|
|
189
|
+
return /* @__PURE__ */ jsx6("div", { className: "flex items-center justify-center py-12 text-muted-foreground", children: "Loading..." });
|
|
190
|
+
}
|
|
191
|
+
if (!user) {
|
|
192
|
+
return /* @__PURE__ */ jsxs4("div", { className: "container max-w-4xl py-8", children: [
|
|
193
|
+
/* @__PURE__ */ jsxs4("div", { className: "mb-8", children: [
|
|
194
|
+
/* @__PURE__ */ jsx6("h1", { className: "text-2xl font-semibold tracking-tight", children: "Profile" }),
|
|
195
|
+
/* @__PURE__ */ jsx6("p", { className: "text-muted-foreground", children: "Manage your account information" })
|
|
196
|
+
] }),
|
|
197
|
+
/* @__PURE__ */ jsx6("div", { className: "flex items-center justify-center rounded-[var(--radius-md)] border border-dashed py-24", children: /* @__PURE__ */ jsx6("p", { className: "text-muted-foreground text-sm", children: "Please sign in to view your profile." }) })
|
|
198
|
+
] });
|
|
199
|
+
}
|
|
200
|
+
return /* @__PURE__ */ jsxs4("div", { className: "container max-w-4xl py-8", children: [
|
|
201
|
+
/* @__PURE__ */ jsxs4("div", { className: "mb-8", children: [
|
|
202
|
+
/* @__PURE__ */ jsx6("h1", { className: "text-2xl font-semibold tracking-tight", children: "Profile" }),
|
|
203
|
+
/* @__PURE__ */ jsx6("p", { className: "text-muted-foreground", children: "Manage your account information" })
|
|
204
|
+
] }),
|
|
205
|
+
/* @__PURE__ */ jsx6(WidgetErrorBoundary, { widgetName: "profile", children: /* @__PURE__ */ jsx6(UserProfile, { authToken: getAccessToken }) })
|
|
206
|
+
] });
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// src/widgets/user-security.tsx
|
|
210
|
+
import { UserSecurity as WorkOSUserSecurity } from "@workos-inc/widgets";
|
|
211
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
212
|
+
function UserSecurity({ authToken, className }) {
|
|
213
|
+
return /* @__PURE__ */ jsx7("div", { className, children: /* @__PURE__ */ jsx7(WorkOSUserSecurity, { authToken }) });
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// src/shell/pages/security-page.tsx
|
|
217
|
+
import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
218
|
+
function SecurityPage() {
|
|
219
|
+
const { user, getAccessToken, isLoading } = useAuth();
|
|
220
|
+
if (isLoading) {
|
|
221
|
+
return /* @__PURE__ */ jsx8("div", { className: "flex items-center justify-center py-12 text-muted-foreground", children: "Loading..." });
|
|
222
|
+
}
|
|
223
|
+
if (!user) {
|
|
224
|
+
return /* @__PURE__ */ jsxs5("div", { className: "container max-w-4xl py-8", children: [
|
|
225
|
+
/* @__PURE__ */ jsxs5("div", { className: "mb-8", children: [
|
|
226
|
+
/* @__PURE__ */ jsx8("h1", { className: "text-2xl font-semibold tracking-tight", children: "Security" }),
|
|
227
|
+
/* @__PURE__ */ jsx8("p", { className: "text-muted-foreground", children: "Manage your password and authentication settings" })
|
|
228
|
+
] }),
|
|
229
|
+
/* @__PURE__ */ jsx8("div", { className: "flex items-center justify-center rounded-[var(--radius-md)] border border-dashed py-24", children: /* @__PURE__ */ jsx8("p", { className: "text-muted-foreground text-sm", children: "Please sign in to manage your security settings." }) })
|
|
230
|
+
] });
|
|
231
|
+
}
|
|
232
|
+
return /* @__PURE__ */ jsxs5("div", { className: "container max-w-4xl py-8", children: [
|
|
233
|
+
/* @__PURE__ */ jsxs5("div", { className: "mb-8", children: [
|
|
234
|
+
/* @__PURE__ */ jsx8("h1", { className: "text-2xl font-semibold tracking-tight", children: "Security" }),
|
|
235
|
+
/* @__PURE__ */ jsx8("p", { className: "text-muted-foreground", children: "Manage your password and authentication settings" })
|
|
236
|
+
] }),
|
|
237
|
+
/* @__PURE__ */ jsx8(WidgetErrorBoundary, { widgetName: "security", children: /* @__PURE__ */ jsx8(UserSecurity, { authToken: getAccessToken }) })
|
|
238
|
+
] });
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// src/widgets/user-sessions.tsx
|
|
242
|
+
import { UserSessions as WorkOSUserSessions } from "@workos-inc/widgets";
|
|
243
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
244
|
+
function UserSessions(props) {
|
|
245
|
+
const { className, ...rest } = props;
|
|
246
|
+
return /* @__PURE__ */ jsx9("div", { className, children: /* @__PURE__ */ jsx9(WorkOSUserSessions, { ...rest }) });
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// src/shell/pages/sessions-page.tsx
|
|
250
|
+
import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
251
|
+
function SessionsPage() {
|
|
252
|
+
const { user, getAccessToken, isLoading } = useAuth();
|
|
253
|
+
if (isLoading) {
|
|
254
|
+
return /* @__PURE__ */ jsx10("div", { className: "flex items-center justify-center py-12 text-muted-foreground", children: "Loading..." });
|
|
255
|
+
}
|
|
256
|
+
if (!user) {
|
|
257
|
+
return /* @__PURE__ */ jsxs6("div", { className: "container max-w-4xl py-8", children: [
|
|
258
|
+
/* @__PURE__ */ jsxs6("div", { className: "mb-8", children: [
|
|
259
|
+
/* @__PURE__ */ jsx10("h1", { className: "text-2xl font-semibold tracking-tight", children: "Sessions" }),
|
|
260
|
+
/* @__PURE__ */ jsx10("p", { className: "text-muted-foreground", children: "View and manage your active sessions" })
|
|
261
|
+
] }),
|
|
262
|
+
/* @__PURE__ */ jsx10("div", { className: "flex items-center justify-center rounded-[var(--radius-md)] border border-dashed py-24", children: /* @__PURE__ */ jsx10("p", { className: "text-muted-foreground text-sm", children: "Please sign in to view your sessions." }) })
|
|
263
|
+
] });
|
|
264
|
+
}
|
|
265
|
+
return /* @__PURE__ */ jsxs6("div", { className: "container max-w-4xl py-8", children: [
|
|
266
|
+
/* @__PURE__ */ jsxs6("div", { className: "mb-8", children: [
|
|
267
|
+
/* @__PURE__ */ jsx10("h1", { className: "text-2xl font-semibold tracking-tight", children: "Sessions" }),
|
|
268
|
+
/* @__PURE__ */ jsx10("p", { className: "text-muted-foreground", children: "View and manage your active sessions" })
|
|
269
|
+
] }),
|
|
270
|
+
/* @__PURE__ */ jsx10(WidgetErrorBoundary, { widgetName: "sessions", children: /* @__PURE__ */ jsx10(UserSessions, { authToken: getAccessToken }) })
|
|
271
|
+
] });
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// src/widgets/api-keys.tsx
|
|
275
|
+
import { ApiKeys as WorkOSApiKeys } from "@workos-inc/widgets";
|
|
276
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
277
|
+
function ApiKeys({ authToken, className }) {
|
|
278
|
+
return /* @__PURE__ */ jsx11("div", { className, children: /* @__PURE__ */ jsx11(WorkOSApiKeys, { authToken }) });
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// src/shell/pages/api-keys-page.tsx
|
|
282
|
+
import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
283
|
+
function ApiKeysPage() {
|
|
284
|
+
const { user, getAccessToken, isLoading } = useAuth();
|
|
285
|
+
if (isLoading) {
|
|
286
|
+
return /* @__PURE__ */ jsx12("div", { className: "flex items-center justify-center py-12 text-muted-foreground", children: "Loading..." });
|
|
287
|
+
}
|
|
288
|
+
if (!user) {
|
|
289
|
+
return /* @__PURE__ */ jsxs7("div", { className: "container max-w-4xl py-8", children: [
|
|
290
|
+
/* @__PURE__ */ jsxs7("div", { className: "mb-8", children: [
|
|
291
|
+
/* @__PURE__ */ jsx12("h1", { className: "text-2xl font-semibold tracking-tight", children: "API Keys" }),
|
|
292
|
+
/* @__PURE__ */ jsx12("p", { className: "text-muted-foreground", children: "Create and manage your API keys" })
|
|
293
|
+
] }),
|
|
294
|
+
/* @__PURE__ */ jsx12("div", { className: "flex items-center justify-center rounded-[var(--radius-md)] border border-dashed py-24", children: /* @__PURE__ */ jsx12("p", { className: "text-muted-foreground text-sm", children: "Please sign in to manage your API keys." }) })
|
|
295
|
+
] });
|
|
296
|
+
}
|
|
297
|
+
return /* @__PURE__ */ jsxs7("div", { className: "container max-w-4xl py-8", children: [
|
|
298
|
+
/* @__PURE__ */ jsxs7("div", { className: "mb-8", children: [
|
|
299
|
+
/* @__PURE__ */ jsx12("h1", { className: "text-2xl font-semibold tracking-tight", children: "API Keys" }),
|
|
300
|
+
/* @__PURE__ */ jsx12("p", { className: "text-muted-foreground", children: "Create and manage your API keys" })
|
|
301
|
+
] }),
|
|
302
|
+
/* @__PURE__ */ jsx12(WidgetErrorBoundary, { widgetName: "api-keys", children: /* @__PURE__ */ jsx12(ApiKeys, { authToken: getAccessToken }) })
|
|
303
|
+
] });
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// src/widgets/users-management.tsx
|
|
307
|
+
import { UsersManagement as WorkOSUsersManagement } from "@workos-inc/widgets";
|
|
308
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
309
|
+
function UsersManagement({
|
|
310
|
+
authToken,
|
|
311
|
+
organizationId: _organizationId,
|
|
312
|
+
className
|
|
313
|
+
}) {
|
|
314
|
+
return /* @__PURE__ */ jsx13("div", { className, children: /* @__PURE__ */ jsx13(WorkOSUsersManagement, { authToken }) });
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// src/shell/pages/team-page.tsx
|
|
318
|
+
import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
319
|
+
function TeamPage() {
|
|
320
|
+
const { user, getAccessToken, isLoading, organizationId, permissions } = useAuth();
|
|
321
|
+
const hasOrganization = !!organizationId;
|
|
322
|
+
const canManageTeam = hasOrganization && permissions?.includes("widgets:users-table:manage");
|
|
323
|
+
if (isLoading) {
|
|
324
|
+
return /* @__PURE__ */ jsx14("div", { className: "flex items-center justify-center py-12 text-muted-foreground", children: "Loading..." });
|
|
325
|
+
}
|
|
326
|
+
if (!user) {
|
|
327
|
+
return /* @__PURE__ */ jsxs8("div", { className: "container max-w-4xl py-8", children: [
|
|
328
|
+
/* @__PURE__ */ jsxs8("div", { className: "mb-8", children: [
|
|
329
|
+
/* @__PURE__ */ jsx14("h1", { className: "text-2xl font-semibold tracking-tight", children: "Team" }),
|
|
330
|
+
/* @__PURE__ */ jsx14("p", { className: "text-muted-foreground", children: "Manage your team members and invitations" })
|
|
331
|
+
] }),
|
|
332
|
+
/* @__PURE__ */ jsx14("div", { className: "flex items-center justify-center rounded-[var(--radius-md)] border border-dashed py-24", children: /* @__PURE__ */ jsx14("p", { className: "text-muted-foreground text-sm", children: "Please sign in to manage your team." }) })
|
|
333
|
+
] });
|
|
334
|
+
}
|
|
335
|
+
if (!hasOrganization) {
|
|
336
|
+
return /* @__PURE__ */ jsxs8("div", { className: "container max-w-4xl py-8", children: [
|
|
337
|
+
/* @__PURE__ */ jsxs8("div", { className: "mb-8", children: [
|
|
338
|
+
/* @__PURE__ */ jsx14("h1", { className: "text-2xl font-semibold tracking-tight", children: "Team" }),
|
|
339
|
+
/* @__PURE__ */ jsx14("p", { className: "text-muted-foreground", children: "Manage your team members and invitations" })
|
|
340
|
+
] }),
|
|
341
|
+
/* @__PURE__ */ jsx14("div", { className: "flex items-center justify-center rounded-[var(--radius-md)] border border-dashed py-24", children: /* @__PURE__ */ jsx14("p", { className: "text-muted-foreground text-sm", children: "You need to be part of an organization to manage team members." }) })
|
|
342
|
+
] });
|
|
343
|
+
}
|
|
344
|
+
if (!canManageTeam) {
|
|
345
|
+
return /* @__PURE__ */ jsxs8("div", { className: "container max-w-4xl py-8", children: [
|
|
346
|
+
/* @__PURE__ */ jsxs8("div", { className: "mb-8", children: [
|
|
347
|
+
/* @__PURE__ */ jsx14("h1", { className: "text-2xl font-semibold tracking-tight", children: "Team" }),
|
|
348
|
+
/* @__PURE__ */ jsx14("p", { className: "text-muted-foreground", children: "Manage your team members and invitations" })
|
|
349
|
+
] }),
|
|
350
|
+
/* @__PURE__ */ jsx14("div", { className: "flex items-center justify-center rounded-[var(--radius-md)] border border-dashed py-24", children: /* @__PURE__ */ jsx14("p", { className: "text-muted-foreground text-sm", children: "You need admin permissions to manage team members." }) })
|
|
351
|
+
] });
|
|
352
|
+
}
|
|
353
|
+
return /* @__PURE__ */ jsxs8("div", { className: "container max-w-4xl py-8", children: [
|
|
354
|
+
/* @__PURE__ */ jsxs8("div", { className: "mb-8", children: [
|
|
355
|
+
/* @__PURE__ */ jsx14("h1", { className: "text-2xl font-semibold tracking-tight", children: "Team" }),
|
|
356
|
+
/* @__PURE__ */ jsx14("p", { className: "text-muted-foreground", children: "Manage your team members and invitations" })
|
|
357
|
+
] }),
|
|
358
|
+
/* @__PURE__ */ jsx14(WidgetErrorBoundary, { widgetName: "team", children: /* @__PURE__ */ jsx14(UsersManagement, { authToken: getAccessToken }) })
|
|
359
|
+
] });
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// src/widgets/pipes.tsx
|
|
363
|
+
import { Pipes as WorkOSPipes } from "@workos-inc/widgets";
|
|
364
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
365
|
+
function Pipes({ authToken, className }) {
|
|
366
|
+
return /* @__PURE__ */ jsx15("div", { className, children: /* @__PURE__ */ jsx15(WorkOSPipes, { authToken }) });
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// src/shell/pages/integrations-page.tsx
|
|
370
|
+
import { jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
371
|
+
function IntegrationsPage() {
|
|
372
|
+
const { user, getAccessToken, isLoading } = useAuth();
|
|
373
|
+
if (isLoading) {
|
|
374
|
+
return /* @__PURE__ */ jsx16("div", { className: "flex items-center justify-center py-12 text-muted-foreground", children: "Loading..." });
|
|
375
|
+
}
|
|
376
|
+
if (!user) {
|
|
377
|
+
return /* @__PURE__ */ jsxs9("div", { className: "container max-w-4xl py-8", children: [
|
|
378
|
+
/* @__PURE__ */ jsxs9("div", { className: "mb-8", children: [
|
|
379
|
+
/* @__PURE__ */ jsx16("h1", { className: "text-2xl font-semibold tracking-tight", children: "Integrations" }),
|
|
380
|
+
/* @__PURE__ */ jsx16("p", { className: "text-muted-foreground", children: "Connect and manage third-party services" })
|
|
381
|
+
] }),
|
|
382
|
+
/* @__PURE__ */ jsx16("div", { className: "flex items-center justify-center rounded-[var(--radius-md)] border border-dashed py-24", children: /* @__PURE__ */ jsx16("p", { className: "text-muted-foreground text-sm", children: "Please sign in to manage your integrations." }) })
|
|
383
|
+
] });
|
|
384
|
+
}
|
|
385
|
+
return /* @__PURE__ */ jsxs9("div", { className: "container max-w-4xl py-8", children: [
|
|
386
|
+
/* @__PURE__ */ jsxs9("div", { className: "mb-8", children: [
|
|
387
|
+
/* @__PURE__ */ jsx16("h1", { className: "text-2xl font-semibold tracking-tight", children: "Integrations" }),
|
|
388
|
+
/* @__PURE__ */ jsx16("p", { className: "text-muted-foreground", children: "Connect and manage third-party services" })
|
|
389
|
+
] }),
|
|
390
|
+
/* @__PURE__ */ jsx16(WidgetErrorBoundary, { widgetName: "integrations", children: /* @__PURE__ */ jsx16(Pipes, { authToken: getAccessToken }) })
|
|
391
|
+
] });
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// src/shell/route-presets.ts
|
|
395
|
+
var defaultGroups = [
|
|
396
|
+
{ id: "main", order: 0 },
|
|
397
|
+
{ id: "account", label: "Account", order: 10 },
|
|
398
|
+
{ id: "developer", label: "Developer", order: 20 },
|
|
399
|
+
{ id: "admin", label: "Admin", order: 30 }
|
|
400
|
+
];
|
|
401
|
+
var accountRoutes = [
|
|
402
|
+
{
|
|
403
|
+
key: "profile",
|
|
404
|
+
path: "/profile",
|
|
405
|
+
label: "Profile",
|
|
406
|
+
group: "account",
|
|
407
|
+
icon: User,
|
|
408
|
+
component: ProfilePage,
|
|
409
|
+
enabled: true,
|
|
410
|
+
public: false
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
key: "security",
|
|
414
|
+
path: "/security",
|
|
415
|
+
label: "Security",
|
|
416
|
+
group: "account",
|
|
417
|
+
icon: Shield,
|
|
418
|
+
component: SecurityPage,
|
|
419
|
+
enabled: true,
|
|
420
|
+
public: false
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
key: "sessions",
|
|
424
|
+
path: "/sessions",
|
|
425
|
+
label: "Sessions",
|
|
426
|
+
group: "account",
|
|
427
|
+
icon: Monitor,
|
|
428
|
+
component: SessionsPage,
|
|
429
|
+
enabled: true,
|
|
430
|
+
public: false
|
|
431
|
+
}
|
|
432
|
+
];
|
|
433
|
+
var developerRoutes = [
|
|
434
|
+
{
|
|
435
|
+
key: "api-keys",
|
|
436
|
+
path: "/api-keys",
|
|
437
|
+
label: "API Keys",
|
|
438
|
+
group: "developer",
|
|
439
|
+
icon: Key,
|
|
440
|
+
component: ApiKeysPage,
|
|
441
|
+
enabled: true,
|
|
442
|
+
public: false
|
|
443
|
+
}
|
|
444
|
+
];
|
|
445
|
+
var adminRoutes = [
|
|
446
|
+
{
|
|
447
|
+
key: "team",
|
|
448
|
+
path: "/team",
|
|
449
|
+
label: "Team",
|
|
450
|
+
group: "admin",
|
|
451
|
+
icon: Users,
|
|
452
|
+
component: TeamPage,
|
|
453
|
+
enabled: true,
|
|
454
|
+
public: false
|
|
455
|
+
}
|
|
456
|
+
];
|
|
457
|
+
var integrationRoutes = [
|
|
458
|
+
{
|
|
459
|
+
key: "integrations",
|
|
460
|
+
path: "/integrations",
|
|
461
|
+
label: "Integrations",
|
|
462
|
+
group: "developer",
|
|
463
|
+
icon: Plug,
|
|
464
|
+
component: IntegrationsPage,
|
|
465
|
+
enabled: true,
|
|
466
|
+
public: false
|
|
467
|
+
}
|
|
468
|
+
];
|
|
469
|
+
var defaultRoutes = [
|
|
470
|
+
...accountRoutes,
|
|
471
|
+
...developerRoutes,
|
|
472
|
+
...adminRoutes
|
|
473
|
+
];
|
|
474
|
+
|
|
475
|
+
// src/shell/config-context.tsx
|
|
476
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
477
|
+
var AuthShellConfigContext = createContext(null);
|
|
478
|
+
function AuthShellConfigProvider({ config, children }) {
|
|
479
|
+
const value = useMemo(() => {
|
|
480
|
+
const routes = config.routes ?? defaultRoutes;
|
|
481
|
+
const enabledRoutes = routes.filter((route) => route.enabled !== false);
|
|
482
|
+
const groups = [...config.groups ?? defaultGroups].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
|
|
483
|
+
const routesByGroup = /* @__PURE__ */ new Map();
|
|
484
|
+
for (const group of groups) {
|
|
485
|
+
routesByGroup.set(group.id, []);
|
|
486
|
+
}
|
|
487
|
+
for (const route of enabledRoutes) {
|
|
488
|
+
const groupId = route.group ?? "main";
|
|
489
|
+
const groupRoutes = routesByGroup.get(groupId) ?? [];
|
|
490
|
+
groupRoutes.push(route);
|
|
491
|
+
routesByGroup.set(groupId, groupRoutes);
|
|
492
|
+
}
|
|
493
|
+
for (const [groupId, routes2] of routesByGroup) {
|
|
494
|
+
routesByGroup.set(
|
|
495
|
+
groupId,
|
|
496
|
+
routes2.sort((a, b) => (a.order ?? 0) - (b.order ?? 0))
|
|
497
|
+
);
|
|
498
|
+
}
|
|
499
|
+
return {
|
|
500
|
+
config,
|
|
501
|
+
routes: enabledRoutes,
|
|
502
|
+
routesByGroup,
|
|
503
|
+
groups,
|
|
504
|
+
branding: config.branding,
|
|
505
|
+
basePath: config.basePath ?? ""
|
|
506
|
+
};
|
|
507
|
+
}, [config]);
|
|
508
|
+
return /* @__PURE__ */ jsx17(AuthShellConfigContext.Provider, { value, children });
|
|
509
|
+
}
|
|
510
|
+
function useAuthShellConfig() {
|
|
511
|
+
const context = useContext(AuthShellConfigContext);
|
|
512
|
+
if (!context) {
|
|
513
|
+
throw new Error("useAuthShellConfig must be used within AuthShellConfigProvider");
|
|
514
|
+
}
|
|
515
|
+
return context;
|
|
516
|
+
}
|
|
517
|
+
function useAuthShellRoutes() {
|
|
518
|
+
const { routes } = useAuthShellConfig();
|
|
519
|
+
return routes;
|
|
520
|
+
}
|
|
521
|
+
function useAuthShellRoutesByGroup() {
|
|
522
|
+
const { routesByGroup, groups } = useAuthShellConfig();
|
|
523
|
+
return { routesByGroup, groups };
|
|
524
|
+
}
|
|
525
|
+
function useAuthShellBranding() {
|
|
526
|
+
const { branding } = useAuthShellConfig();
|
|
527
|
+
return branding;
|
|
528
|
+
}
|
|
529
|
+
function useAuthShellFullPath() {
|
|
530
|
+
const { basePath } = useAuthShellConfig();
|
|
531
|
+
return useMemo(() => {
|
|
532
|
+
return (path) => {
|
|
533
|
+
if (!basePath) return path;
|
|
534
|
+
if (path === "/") return basePath || "/";
|
|
535
|
+
return `${basePath}${path}`;
|
|
536
|
+
};
|
|
537
|
+
}, [basePath]);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// src/shell/auth-shell.tsx
|
|
541
|
+
import { Separator } from "@mdxui/primitives/separator";
|
|
542
|
+
import {
|
|
543
|
+
SidebarInset,
|
|
544
|
+
SidebarProvider,
|
|
545
|
+
SidebarTrigger
|
|
546
|
+
} from "@mdxui/primitives/sidebar";
|
|
547
|
+
import { Toaster } from "@mdxui/primitives/sonner";
|
|
548
|
+
|
|
549
|
+
// src/providers/auth-gate.tsx
|
|
550
|
+
import { useEffect, useRef } from "react";
|
|
551
|
+
import { useAuth as useAuth3 } from "@workos-inc/authkit-react";
|
|
552
|
+
import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
553
|
+
function DefaultLoadingComponent() {
|
|
554
|
+
return /* @__PURE__ */ jsx18("div", { className: "min-h-screen bg-background flex items-center justify-center", children: /* @__PURE__ */ jsxs10("div", { className: "flex flex-col items-center gap-4", children: [
|
|
555
|
+
/* @__PURE__ */ jsx18("div", { className: "h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent" }),
|
|
556
|
+
/* @__PURE__ */ jsx18("p", { className: "text-sm text-muted-foreground", children: "Loading..." })
|
|
557
|
+
] }) });
|
|
558
|
+
}
|
|
559
|
+
function DefaultLandingPage() {
|
|
560
|
+
const { signIn } = useAuth3();
|
|
561
|
+
return /* @__PURE__ */ jsx18("div", { className: "min-h-screen bg-background flex flex-col items-center justify-center p-4", children: /* @__PURE__ */ jsxs10("div", { className: "text-center max-w-md", children: [
|
|
562
|
+
/* @__PURE__ */ jsx18("h1", { className: "text-3xl font-bold tracking-tight mb-4", children: "Welcome" }),
|
|
563
|
+
/* @__PURE__ */ jsx18("p", { className: "text-muted-foreground mb-8", children: "Sign in to access your dashboard." }),
|
|
564
|
+
/* @__PURE__ */ jsx18(
|
|
565
|
+
"button",
|
|
566
|
+
{
|
|
567
|
+
type: "button",
|
|
568
|
+
onClick: () => signIn(),
|
|
569
|
+
className: "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-[var(--radius-md)] text-sm font-medium transition-colors bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-6",
|
|
570
|
+
children: "Sign In"
|
|
571
|
+
}
|
|
572
|
+
)
|
|
573
|
+
] }) });
|
|
574
|
+
}
|
|
575
|
+
function AuthGate({
|
|
576
|
+
children,
|
|
577
|
+
required = true,
|
|
578
|
+
loadingComponent,
|
|
579
|
+
landingComponent,
|
|
580
|
+
onUnauthenticated = "landing",
|
|
581
|
+
redirectUrl
|
|
582
|
+
}) {
|
|
583
|
+
const { user, isLoading, signIn } = useAuth3();
|
|
584
|
+
const signInCalled = useRef(false);
|
|
585
|
+
useEffect(() => {
|
|
586
|
+
if (onUnauthenticated === "signIn" && !isLoading && !user && !signInCalled.current) {
|
|
587
|
+
signInCalled.current = true;
|
|
588
|
+
signIn();
|
|
589
|
+
}
|
|
590
|
+
}, [onUnauthenticated, isLoading, user, signIn]);
|
|
591
|
+
useEffect(() => {
|
|
592
|
+
if (user) {
|
|
593
|
+
signInCalled.current = false;
|
|
594
|
+
}
|
|
595
|
+
}, [user]);
|
|
596
|
+
if (!required) {
|
|
597
|
+
return /* @__PURE__ */ jsx18(Fragment2, { children });
|
|
598
|
+
}
|
|
599
|
+
if (isLoading) {
|
|
600
|
+
return /* @__PURE__ */ jsx18(Fragment2, { children: loadingComponent ?? /* @__PURE__ */ jsx18(DefaultLoadingComponent, {}) });
|
|
601
|
+
}
|
|
602
|
+
if (user) {
|
|
603
|
+
return /* @__PURE__ */ jsx18(Fragment2, { children });
|
|
604
|
+
}
|
|
605
|
+
switch (onUnauthenticated) {
|
|
606
|
+
case "signIn":
|
|
607
|
+
return /* @__PURE__ */ jsx18(Fragment2, { children: loadingComponent ?? /* @__PURE__ */ jsx18(DefaultLoadingComponent, {}) });
|
|
608
|
+
case "redirect":
|
|
609
|
+
if (redirectUrl && typeof window !== "undefined") {
|
|
610
|
+
window.location.href = redirectUrl;
|
|
611
|
+
return /* @__PURE__ */ jsx18("div", { className: "min-h-screen bg-background flex items-center justify-center", children: /* @__PURE__ */ jsx18("p", { className: "text-sm text-muted-foreground", children: "Redirecting..." }) });
|
|
612
|
+
}
|
|
613
|
+
return /* @__PURE__ */ jsx18(Fragment2, { children: landingComponent ?? /* @__PURE__ */ jsx18(DefaultLandingPage, {}) });
|
|
614
|
+
case "allow":
|
|
615
|
+
return /* @__PURE__ */ jsx18(Fragment2, { children });
|
|
616
|
+
case "landing":
|
|
617
|
+
default:
|
|
618
|
+
return /* @__PURE__ */ jsx18(Fragment2, { children: landingComponent ?? /* @__PURE__ */ jsx18(DefaultLandingPage, {}) });
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
// src/shell/auth-shell-nav.tsx
|
|
623
|
+
import { useAuth as useAuth4 } from "@workos-inc/authkit-react";
|
|
624
|
+
import { useIsActive, WebLink as WebLink2 } from "@mdxui/navigation/web";
|
|
625
|
+
import {
|
|
626
|
+
Sidebar,
|
|
627
|
+
SidebarContent,
|
|
628
|
+
SidebarFooter,
|
|
629
|
+
SidebarGroup,
|
|
630
|
+
SidebarGroupContent,
|
|
631
|
+
SidebarGroupLabel,
|
|
632
|
+
SidebarHeader,
|
|
633
|
+
SidebarMenu,
|
|
634
|
+
SidebarMenuButton,
|
|
635
|
+
SidebarMenuItem,
|
|
636
|
+
SidebarRail
|
|
637
|
+
} from "@mdxui/primitives/sidebar";
|
|
638
|
+
import { SidebarUser } from "@mdxui/primitives/sidebar-user";
|
|
639
|
+
import { Fragment as Fragment3, jsx as jsx19, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
640
|
+
function NavItem({ route, getFullPath }) {
|
|
641
|
+
const fullPath = getFullPath(route.path);
|
|
642
|
+
const isActive = useIsActive(fullPath, { partial: fullPath !== "/" });
|
|
643
|
+
const Icon = route.icon;
|
|
644
|
+
return /* @__PURE__ */ jsx19(SidebarMenuItem, { children: /* @__PURE__ */ jsx19(SidebarMenuButton, { asChild: true, isActive, tooltip: route.label, children: /* @__PURE__ */ jsxs11(WebLink2, { to: fullPath, children: [
|
|
645
|
+
Icon && /* @__PURE__ */ jsx19(Icon, { className: "size-4" }),
|
|
646
|
+
/* @__PURE__ */ jsx19("span", { children: route.label })
|
|
647
|
+
] }) }) });
|
|
648
|
+
}
|
|
649
|
+
function BrandingHeader({ headerContent }) {
|
|
650
|
+
const branding = useAuthShellBranding();
|
|
651
|
+
if (headerContent) {
|
|
652
|
+
return /* @__PURE__ */ jsx19(Fragment3, { children: headerContent });
|
|
653
|
+
}
|
|
654
|
+
return /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 px-2", children: [
|
|
655
|
+
branding.logo && /* @__PURE__ */ jsx19("div", { className: "flex-shrink-0", children: branding.logo }),
|
|
656
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-0.5 leading-none", children: [
|
|
657
|
+
/* @__PURE__ */ jsx19("span", { className: "font-semibold", children: branding.name }),
|
|
658
|
+
branding.tagline && /* @__PURE__ */ jsx19("span", { className: "text-xs text-muted-foreground", children: branding.tagline })
|
|
659
|
+
] })
|
|
660
|
+
] });
|
|
661
|
+
}
|
|
662
|
+
function DefaultUserMenu() {
|
|
663
|
+
const { user, signOut } = useAuth4();
|
|
664
|
+
if (!user) return null;
|
|
665
|
+
const displayName = user.firstName ? `${user.firstName}${user.lastName ? ` ${user.lastName}` : ""}` : user.email ?? "User";
|
|
666
|
+
return /* @__PURE__ */ jsx19(
|
|
667
|
+
SidebarUser,
|
|
668
|
+
{
|
|
669
|
+
user: {
|
|
670
|
+
name: displayName,
|
|
671
|
+
email: user.email ?? "",
|
|
672
|
+
avatar: user.profilePictureUrl ?? void 0
|
|
673
|
+
},
|
|
674
|
+
onSignOut: () => signOut()
|
|
675
|
+
}
|
|
676
|
+
);
|
|
677
|
+
}
|
|
678
|
+
function AuthShellNav({ headerContent, userMenu, className }) {
|
|
679
|
+
const { routesByGroup, groups } = useAuthShellRoutesByGroup();
|
|
680
|
+
const getFullPath = useAuthShellFullPath();
|
|
681
|
+
return /* @__PURE__ */ jsxs11(Sidebar, { collapsible: "icon", className, children: [
|
|
682
|
+
/* @__PURE__ */ jsx19(SidebarHeader, { children: /* @__PURE__ */ jsx19(BrandingHeader, { headerContent }) }),
|
|
683
|
+
/* @__PURE__ */ jsx19(SidebarContent, { children: groups.map((group) => {
|
|
684
|
+
const routes = routesByGroup.get(group.id);
|
|
685
|
+
if (!routes || routes.length === 0) return null;
|
|
686
|
+
return /* @__PURE__ */ jsxs11(SidebarGroup, { children: [
|
|
687
|
+
group.label && /* @__PURE__ */ jsx19(SidebarGroupLabel, { children: group.label }),
|
|
688
|
+
/* @__PURE__ */ jsx19(SidebarGroupContent, { children: /* @__PURE__ */ jsx19(SidebarMenu, { children: routes.map((route) => /* @__PURE__ */ jsx19(NavItem, { route, getFullPath }, route.key)) }) })
|
|
689
|
+
] }, group.id);
|
|
690
|
+
}) }),
|
|
691
|
+
/* @__PURE__ */ jsx19(SidebarFooter, { children: userMenu ?? /* @__PURE__ */ jsx19(DefaultUserMenu, {}) }),
|
|
692
|
+
/* @__PURE__ */ jsx19(SidebarRail, {})
|
|
693
|
+
] });
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
// src/shell/auth-shell.tsx
|
|
697
|
+
import { jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
698
|
+
function DefaultHeader({
|
|
699
|
+
breadcrumbs,
|
|
700
|
+
headerContent
|
|
701
|
+
}) {
|
|
702
|
+
return /* @__PURE__ */ jsxs12("header", { className: "relative flex h-16 shrink-0 items-center gap-2 border-b bg-background transition-[width,height] ease-linear group-has-data-[collapsible=icon]/sidebar-wrapper:h-12", children: [
|
|
703
|
+
/* @__PURE__ */ jsxs12("div", { className: "z-10 flex shrink-0 items-center gap-2 bg-background px-4", children: [
|
|
704
|
+
/* @__PURE__ */ jsx20(SidebarTrigger, { className: "-ml-1" }),
|
|
705
|
+
/* @__PURE__ */ jsx20(Separator, { orientation: "vertical", className: "mr-2 h-4" }),
|
|
706
|
+
breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx20(Breadcrumbs, { items: breadcrumbs })
|
|
707
|
+
] }),
|
|
708
|
+
headerContent && /* @__PURE__ */ jsx20("div", { className: "flex flex-1 items-center px-4 xl:absolute xl:inset-0 xl:justify-center", children: /* @__PURE__ */ jsx20("div", { className: "w-full max-w-md", children: headerContent }) })
|
|
709
|
+
] });
|
|
710
|
+
}
|
|
711
|
+
function AuthShell({
|
|
712
|
+
children,
|
|
713
|
+
sidebarHeaderContent,
|
|
714
|
+
headerContent,
|
|
715
|
+
breadcrumbs
|
|
716
|
+
}) {
|
|
717
|
+
const { config } = useAuthShellConfig();
|
|
718
|
+
const { identity, auth } = config;
|
|
719
|
+
return /* @__PURE__ */ jsxs12(
|
|
720
|
+
AuthGate,
|
|
721
|
+
{
|
|
722
|
+
required: identity.required ?? auth?.requireAuth ?? true,
|
|
723
|
+
onUnauthenticated: identity.onUnauthenticated ?? auth?.onUnauthenticated ?? "landing",
|
|
724
|
+
loadingComponent: identity.loadingComponent,
|
|
725
|
+
landingComponent: identity.landingComponent,
|
|
726
|
+
children: [
|
|
727
|
+
/* @__PURE__ */ jsxs12(SidebarProvider, { children: [
|
|
728
|
+
/* @__PURE__ */ jsx20(AuthShellNav, { headerContent: sidebarHeaderContent }),
|
|
729
|
+
/* @__PURE__ */ jsxs12(SidebarInset, { children: [
|
|
730
|
+
/* @__PURE__ */ jsx20(DefaultHeader, { breadcrumbs, headerContent }),
|
|
731
|
+
/* @__PURE__ */ jsx20("main", { className: "flex-1 overflow-auto p-4", children })
|
|
732
|
+
] })
|
|
733
|
+
] }),
|
|
734
|
+
/* @__PURE__ */ jsx20(Toaster, {})
|
|
735
|
+
]
|
|
736
|
+
}
|
|
737
|
+
);
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
// src/shell/auth-app.tsx
|
|
741
|
+
import { useMemo as useMemo2 } from "react";
|
|
742
|
+
import { ThemeProvider } from "next-themes";
|
|
743
|
+
import { createWebRouter, RouterProvider, WebOutlet } from "@mdxui/navigation/web";
|
|
744
|
+
|
|
745
|
+
// src/providers/identity-provider.tsx
|
|
746
|
+
import { AuthKitProvider } from "@workos-inc/authkit-react";
|
|
747
|
+
|
|
748
|
+
// src/providers/widgets-provider.tsx
|
|
749
|
+
import { WorkOsWidgets } from "@workos-inc/widgets";
|
|
750
|
+
import { useEffect as useEffect2, useState } from "react";
|
|
751
|
+
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
752
|
+
function useThemeDetection() {
|
|
753
|
+
const [mounted, setMounted] = useState(false);
|
|
754
|
+
const [isDark, setIsDark] = useState(false);
|
|
755
|
+
useEffect2(() => {
|
|
756
|
+
setMounted(true);
|
|
757
|
+
const checkDarkMode = () => {
|
|
758
|
+
const isDarkClass = document.documentElement.classList.contains("dark");
|
|
759
|
+
const prefersDark = window.matchMedia(
|
|
760
|
+
"(prefers-color-scheme: dark)"
|
|
761
|
+
).matches;
|
|
762
|
+
setIsDark(
|
|
763
|
+
isDarkClass || !document.documentElement.classList.contains("light") && prefersDark
|
|
764
|
+
);
|
|
765
|
+
};
|
|
766
|
+
checkDarkMode();
|
|
767
|
+
const observer = new MutationObserver(checkDarkMode);
|
|
768
|
+
observer.observe(document.documentElement, {
|
|
769
|
+
attributes: true,
|
|
770
|
+
attributeFilter: ["class"]
|
|
771
|
+
});
|
|
772
|
+
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
773
|
+
mediaQuery.addEventListener("change", checkDarkMode);
|
|
774
|
+
return () => {
|
|
775
|
+
observer.disconnect();
|
|
776
|
+
mediaQuery.removeEventListener("change", checkDarkMode);
|
|
777
|
+
};
|
|
778
|
+
}, []);
|
|
779
|
+
return { isDark, mounted };
|
|
780
|
+
}
|
|
781
|
+
function WidgetsProvider({
|
|
782
|
+
children,
|
|
783
|
+
appearance,
|
|
784
|
+
radius = "medium",
|
|
785
|
+
scaling = "100%"
|
|
786
|
+
}) {
|
|
787
|
+
const { isDark, mounted } = useThemeDetection();
|
|
788
|
+
const resolvedAppearance = appearance ?? (mounted ? isDark ? "dark" : "light" : "inherit");
|
|
789
|
+
return /* @__PURE__ */ jsx21(
|
|
790
|
+
WorkOsWidgets,
|
|
791
|
+
{
|
|
792
|
+
theme: {
|
|
793
|
+
appearance: resolvedAppearance,
|
|
794
|
+
radius,
|
|
795
|
+
scaling
|
|
796
|
+
},
|
|
797
|
+
elements: {
|
|
798
|
+
primaryButton: {
|
|
799
|
+
variant: "solid"
|
|
800
|
+
},
|
|
801
|
+
secondaryButton: {
|
|
802
|
+
variant: "outline"
|
|
803
|
+
}
|
|
804
|
+
},
|
|
805
|
+
children
|
|
806
|
+
}
|
|
807
|
+
);
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
// src/providers/identity-provider.tsx
|
|
811
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
812
|
+
function IdentityProvider({
|
|
813
|
+
clientId,
|
|
814
|
+
apiHostname,
|
|
815
|
+
devMode,
|
|
816
|
+
redirectUri,
|
|
817
|
+
onRedirectCallback,
|
|
818
|
+
children
|
|
819
|
+
}) {
|
|
820
|
+
const resolvedRedirectUri = redirectUri ?? (typeof window !== "undefined" ? window.location.origin : void 0);
|
|
821
|
+
const handleRedirectCallback = onRedirectCallback ?? (() => {
|
|
822
|
+
if (typeof window !== "undefined") {
|
|
823
|
+
const url = new URL(window.location.href);
|
|
824
|
+
url.searchParams.delete("code");
|
|
825
|
+
url.searchParams.delete("state");
|
|
826
|
+
window.history.replaceState({}, "", url.pathname);
|
|
827
|
+
}
|
|
828
|
+
});
|
|
829
|
+
return /* @__PURE__ */ jsx22(
|
|
830
|
+
AuthKitProvider,
|
|
831
|
+
{
|
|
832
|
+
clientId,
|
|
833
|
+
apiHostname,
|
|
834
|
+
devMode,
|
|
835
|
+
redirectUri: resolvedRedirectUri,
|
|
836
|
+
onRedirectCallback: handleRedirectCallback,
|
|
837
|
+
children: /* @__PURE__ */ jsx22(WidgetsProvider, { children })
|
|
838
|
+
}
|
|
839
|
+
);
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
// src/shell/env-config.ts
|
|
843
|
+
function getEnvVar(key) {
|
|
844
|
+
if (typeof import.meta !== "undefined" && import.meta.env) {
|
|
845
|
+
return import.meta.env[key];
|
|
846
|
+
}
|
|
847
|
+
if (typeof process !== "undefined" && process.env) {
|
|
848
|
+
return process.env[key];
|
|
849
|
+
}
|
|
850
|
+
return void 0;
|
|
851
|
+
}
|
|
852
|
+
function getEnvConfig() {
|
|
853
|
+
const clientId = getEnvVar("VITE_WORKOS_CLIENT_ID");
|
|
854
|
+
const redirectUri = getEnvVar("VITE_WORKOS_REDIRECT_URI");
|
|
855
|
+
const apiHostname = getEnvVar("VITE_WORKOS_API_HOSTNAME");
|
|
856
|
+
const devModeStr = getEnvVar("VITE_WORKOS_DEV_MODE");
|
|
857
|
+
const appName = getEnvVar("VITE_APP_NAME");
|
|
858
|
+
const appTagline = getEnvVar("VITE_APP_TAGLINE");
|
|
859
|
+
const identity = clientId ? {
|
|
860
|
+
clientId,
|
|
861
|
+
...redirectUri && { redirectUri },
|
|
862
|
+
...apiHostname && { apiHostname },
|
|
863
|
+
...devModeStr && { devMode: devModeStr === "true" }
|
|
864
|
+
} : void 0;
|
|
865
|
+
const branding = appName ? {
|
|
866
|
+
name: appName,
|
|
867
|
+
...appTagline && { tagline: appTagline }
|
|
868
|
+
} : void 0;
|
|
869
|
+
return {
|
|
870
|
+
...identity && { identity },
|
|
871
|
+
...branding && { branding }
|
|
872
|
+
};
|
|
873
|
+
}
|
|
874
|
+
function mergeWithEnvConfig(config) {
|
|
875
|
+
const envConfig = getEnvConfig();
|
|
876
|
+
const branding = {
|
|
877
|
+
name: config?.branding?.name ?? envConfig.branding?.name ?? "App",
|
|
878
|
+
...config?.branding?.logo && { logo: config.branding.logo },
|
|
879
|
+
...config?.branding?.logoCollapsed && { logoCollapsed: config.branding.logoCollapsed },
|
|
880
|
+
tagline: config?.branding?.tagline ?? envConfig.branding?.tagline
|
|
881
|
+
};
|
|
882
|
+
const envIdentity = envConfig.identity;
|
|
883
|
+
const configIdentity = config?.identity;
|
|
884
|
+
if (!envIdentity?.clientId && !configIdentity?.clientId) {
|
|
885
|
+
throw new Error(
|
|
886
|
+
"AuthApp: Missing clientId. Either provide config.identity.clientId or set VITE_WORKOS_CLIENT_ID environment variable."
|
|
887
|
+
);
|
|
888
|
+
}
|
|
889
|
+
const identity = {
|
|
890
|
+
clientId: configIdentity?.clientId ?? envIdentity?.clientId ?? "",
|
|
891
|
+
...configIdentity?.redirectUri ?? envIdentity?.redirectUri ? { redirectUri: configIdentity?.redirectUri ?? envIdentity?.redirectUri } : {},
|
|
892
|
+
...configIdentity?.apiHostname ?? envIdentity?.apiHostname ? { apiHostname: configIdentity?.apiHostname ?? envIdentity?.apiHostname } : {},
|
|
893
|
+
...configIdentity?.devMode ?? envIdentity?.devMode ? { devMode: configIdentity?.devMode ?? envIdentity?.devMode } : {},
|
|
894
|
+
...configIdentity?.required !== void 0 ? { required: configIdentity.required } : {},
|
|
895
|
+
...configIdentity?.onUnauthenticated ? { onUnauthenticated: configIdentity.onUnauthenticated } : {},
|
|
896
|
+
...configIdentity?.landingComponent ? { landingComponent: configIdentity.landingComponent } : {},
|
|
897
|
+
...configIdentity?.loadingComponent ? { loadingComponent: configIdentity.loadingComponent } : {}
|
|
898
|
+
};
|
|
899
|
+
return {
|
|
900
|
+
branding,
|
|
901
|
+
identity,
|
|
902
|
+
...config?.basePath && { basePath: config.basePath },
|
|
903
|
+
...config?.theme && { theme: config.theme },
|
|
904
|
+
...config?.auth && { auth: config.auth },
|
|
905
|
+
...config?.groups && { groups: config.groups },
|
|
906
|
+
...config?.routes && { routes: config.routes }
|
|
907
|
+
};
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
// src/shell/auth-app.tsx
|
|
911
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
912
|
+
function AuthAppProvider({ config, children }) {
|
|
913
|
+
const resolvedConfig = useMemo2(() => mergeWithEnvConfig(config), [config]);
|
|
914
|
+
const { identity, theme } = resolvedConfig;
|
|
915
|
+
return /* @__PURE__ */ jsx23(
|
|
916
|
+
ThemeProvider,
|
|
917
|
+
{
|
|
918
|
+
attribute: "class",
|
|
919
|
+
defaultTheme: theme?.mode ?? "system",
|
|
920
|
+
enableSystem: true,
|
|
921
|
+
disableTransitionOnChange: true,
|
|
922
|
+
children: /* @__PURE__ */ jsx23(AuthShellConfigProvider, { config: resolvedConfig, children: /* @__PURE__ */ jsx23(
|
|
923
|
+
IdentityProvider,
|
|
924
|
+
{
|
|
925
|
+
clientId: identity.clientId,
|
|
926
|
+
apiHostname: identity.apiHostname,
|
|
927
|
+
devMode: identity.devMode,
|
|
928
|
+
redirectUri: identity.redirectUri,
|
|
929
|
+
children
|
|
930
|
+
}
|
|
931
|
+
) })
|
|
932
|
+
}
|
|
933
|
+
);
|
|
934
|
+
}
|
|
935
|
+
function convertRoutesToConfig(routes, basePath) {
|
|
936
|
+
const config = {};
|
|
937
|
+
for (const route of routes) {
|
|
938
|
+
if (route.enabled === false) continue;
|
|
939
|
+
const fullPath = basePath ? `${basePath}${route.path}` : route.path;
|
|
940
|
+
config[route.key] = {
|
|
941
|
+
path: fullPath,
|
|
942
|
+
component: route.component,
|
|
943
|
+
meta: {
|
|
944
|
+
label: route.label,
|
|
945
|
+
icon: route.icon,
|
|
946
|
+
group: route.group,
|
|
947
|
+
public: route.public,
|
|
948
|
+
requiredRoles: route.requiredRoles,
|
|
949
|
+
requiredPermissions: route.requiredPermissions
|
|
950
|
+
}
|
|
951
|
+
};
|
|
952
|
+
}
|
|
953
|
+
return config;
|
|
954
|
+
}
|
|
955
|
+
function createRootLayout(headerContent, sidebarHeaderContent) {
|
|
956
|
+
const resolvedSidebarContent = sidebarHeaderContent ?? /* @__PURE__ */ jsx23(SidebarOrgSwitcher, {});
|
|
957
|
+
return function RootLayout() {
|
|
958
|
+
return /* @__PURE__ */ jsx23(AuthShell, { headerContent, sidebarHeaderContent: resolvedSidebarContent, children: /* @__PURE__ */ jsx23(WebOutlet, {}) });
|
|
959
|
+
};
|
|
960
|
+
}
|
|
961
|
+
function AuthApp({ config, headerContent, sidebarHeaderContent }) {
|
|
962
|
+
const mergedConfig = useMemo2(() => mergeWithEnvConfig(config), [config]);
|
|
963
|
+
const routes = mergedConfig.routes ?? defaultRoutes;
|
|
964
|
+
const groups = mergedConfig.groups ?? defaultGroups;
|
|
965
|
+
const resolvedConfig = useMemo2(
|
|
966
|
+
() => ({ ...mergedConfig, routes, groups }),
|
|
967
|
+
[mergedConfig, routes, groups]
|
|
968
|
+
);
|
|
969
|
+
const router = useMemo2(() => {
|
|
970
|
+
const routeConfig = convertRoutesToConfig(routes, mergedConfig.basePath);
|
|
971
|
+
const RootLayout = createRootLayout(headerContent, sidebarHeaderContent);
|
|
972
|
+
return createWebRouter(routeConfig, {
|
|
973
|
+
rootComponent: RootLayout,
|
|
974
|
+
basepath: mergedConfig.basePath || void 0
|
|
975
|
+
});
|
|
976
|
+
}, [routes, mergedConfig.basePath, headerContent, sidebarHeaderContent]);
|
|
977
|
+
return /* @__PURE__ */ jsx23(AuthAppProvider, { config: resolvedConfig, children: /* @__PURE__ */ jsx23(RouterProvider, { router }) });
|
|
978
|
+
}
|
|
979
|
+
function AuthAppWithChildren({
|
|
980
|
+
config,
|
|
981
|
+
headerContent,
|
|
982
|
+
sidebarHeaderContent,
|
|
983
|
+
children
|
|
984
|
+
}) {
|
|
985
|
+
const mergedConfig = useMemo2(() => mergeWithEnvConfig(config), [config]);
|
|
986
|
+
const routes = mergedConfig.routes ?? defaultRoutes;
|
|
987
|
+
const groups = mergedConfig.groups ?? defaultGroups;
|
|
988
|
+
const resolvedConfig = useMemo2(
|
|
989
|
+
() => ({ ...mergedConfig, routes, groups }),
|
|
990
|
+
[mergedConfig, routes, groups]
|
|
991
|
+
);
|
|
992
|
+
const resolvedSidebarContent = sidebarHeaderContent ?? /* @__PURE__ */ jsx23(SidebarOrgSwitcher, {});
|
|
993
|
+
return /* @__PURE__ */ jsx23(AuthAppProvider, { config: resolvedConfig, children: /* @__PURE__ */ jsx23(AuthShell, { headerContent, sidebarHeaderContent: resolvedSidebarContent, children }) });
|
|
994
|
+
}
|
|
995
|
+
export {
|
|
996
|
+
ApiKeysPage,
|
|
997
|
+
AuthApp,
|
|
998
|
+
AuthAppProvider,
|
|
999
|
+
AuthAppWithChildren,
|
|
1000
|
+
AuthShell,
|
|
1001
|
+
AuthShellConfigProvider,
|
|
1002
|
+
AuthShellNav,
|
|
1003
|
+
Breadcrumbs,
|
|
1004
|
+
IntegrationsPage,
|
|
1005
|
+
ProfilePage,
|
|
1006
|
+
SecurityPage,
|
|
1007
|
+
SessionsPage,
|
|
1008
|
+
SidebarOrgSwitcher,
|
|
1009
|
+
TeamPage,
|
|
1010
|
+
WidgetErrorBoundary,
|
|
1011
|
+
accountRoutes,
|
|
1012
|
+
adminRoutes,
|
|
1013
|
+
defaultGroups,
|
|
1014
|
+
defaultRoutes,
|
|
1015
|
+
developerRoutes,
|
|
1016
|
+
getEnvConfig,
|
|
1017
|
+
integrationRoutes,
|
|
1018
|
+
mergeWithEnvConfig,
|
|
1019
|
+
useAuthShellBranding,
|
|
1020
|
+
useAuthShellConfig,
|
|
1021
|
+
useAuthShellFullPath,
|
|
1022
|
+
useAuthShellRoutes,
|
|
1023
|
+
useAuthShellRoutesByGroup
|
|
1024
|
+
};
|
|
1025
|
+
//# sourceMappingURL=index.js.map
|