@petrarca/sonnet-shell 0.6.0 → 0.8.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/README.md +56 -211
- package/dist/auth/index.d.ts +54 -12
- package/dist/auth/index.js +136 -113
- package/dist/auth/index.js.map +1 -1
- package/dist/index.d.ts +27 -5
- package/dist/index.js +132 -51
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/auth/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// src/auth/Login.tsx
|
|
2
2
|
import { useState as useState2, useEffect, useCallback as useCallback2 } from "react";
|
|
3
3
|
import { useNavigate, useLocation } from "react-router-dom";
|
|
4
|
+
import { Alert as Alert2 } from "@petrarca/sonnet-ui";
|
|
5
|
+
import { Button as Button2 } from "@petrarca/sonnet-ui";
|
|
4
6
|
import { Input } from "@petrarca/sonnet-ui";
|
|
5
7
|
import { Label } from "@petrarca/sonnet-ui";
|
|
6
8
|
import { Spinner } from "@petrarca/sonnet-ui";
|
|
@@ -10,44 +12,55 @@ import { useState, useCallback } from "react";
|
|
|
10
12
|
import { Check } from "lucide-react";
|
|
11
13
|
import { Button } from "@petrarca/sonnet-ui";
|
|
12
14
|
import { Alert } from "@petrarca/sonnet-ui";
|
|
13
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
15
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
14
16
|
function OrgSelection({
|
|
15
17
|
orgs,
|
|
16
18
|
isLoading,
|
|
17
19
|
error,
|
|
18
|
-
onSelect
|
|
20
|
+
onSelect,
|
|
21
|
+
emptyAction
|
|
19
22
|
}) {
|
|
20
23
|
const [selectedId, setSelectedId] = useState(null);
|
|
24
|
+
const isEmpty = orgs.length === 0;
|
|
21
25
|
const handleContinue = useCallback(() => {
|
|
22
26
|
if (selectedId) onSelect(selectedId);
|
|
23
27
|
}, [selectedId, onSelect]);
|
|
24
|
-
return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center min-h-screen bg-
|
|
28
|
+
return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center min-h-screen bg-muted px-4", children: /* @__PURE__ */ jsxs("div", { className: "w-full max-w-sm bg-card rounded-lg shadow-sm border border-border p-8", children: [
|
|
25
29
|
/* @__PURE__ */ jsxs("div", { className: "mb-6", children: [
|
|
26
|
-
/* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold text-
|
|
27
|
-
/* @__PURE__ */ jsx("p", { className: "text-center text-sm text-
|
|
30
|
+
/* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold text-foreground text-center", children: "Select organization" }),
|
|
31
|
+
/* @__PURE__ */ jsx("p", { className: "text-center text-sm text-muted-foreground mt-1", children: isEmpty ? "No organizations assigned to your account." : "Choose the organization you want to work in." })
|
|
28
32
|
] }),
|
|
29
|
-
error ? /* @__PURE__ */ jsx(
|
|
30
|
-
|
|
31
|
-
"button",
|
|
33
|
+
error ? /* @__PURE__ */ jsx(
|
|
34
|
+
Alert,
|
|
32
35
|
{
|
|
33
|
-
|
|
34
|
-
className:
|
|
35
|
-
children:
|
|
36
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: org.name }),
|
|
37
|
-
selectedId === org.id ? /* @__PURE__ */ jsx(Check, { className: "h-4 w-4 text-blue-500 shrink-0" }) : null
|
|
38
|
-
]
|
|
39
|
-
},
|
|
40
|
-
org.id
|
|
41
|
-
)) }),
|
|
42
|
-
/* @__PURE__ */ jsx(
|
|
43
|
-
Button,
|
|
44
|
-
{
|
|
45
|
-
onClick: handleContinue,
|
|
46
|
-
disabled: !selectedId || isLoading,
|
|
47
|
-
className: "w-full h-10",
|
|
48
|
-
children: isLoading ? "Loading..." : "Continue"
|
|
36
|
+
variant: "destructive",
|
|
37
|
+
className: "mb-4 bg-destructive/10 text-sm py-2.5 px-3",
|
|
38
|
+
children: error
|
|
49
39
|
}
|
|
50
|
-
)
|
|
40
|
+
) : null,
|
|
41
|
+
isEmpty ? emptyAction ? /* @__PURE__ */ jsx("div", { className: "mt-2", children: emptyAction }) : null : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
42
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-2 mb-6 max-h-64 overflow-y-auto", children: orgs.map((org) => /* @__PURE__ */ jsxs(
|
|
43
|
+
"button",
|
|
44
|
+
{
|
|
45
|
+
onClick: () => setSelectedId(org.id),
|
|
46
|
+
className: `w-full flex items-center justify-between px-4 py-3 rounded-md border text-left text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ${selectedId === org.id ? "border-primary bg-state-selected text-foreground" : "border-border hover:bg-state-hover text-foreground"}`,
|
|
47
|
+
children: [
|
|
48
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: org.name }),
|
|
49
|
+
selectedId === org.id ? /* @__PURE__ */ jsx(Check, { className: "h-4 w-4 text-primary shrink-0" }) : null
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
org.id
|
|
53
|
+
)) }),
|
|
54
|
+
/* @__PURE__ */ jsx(
|
|
55
|
+
Button,
|
|
56
|
+
{
|
|
57
|
+
onClick: handleContinue,
|
|
58
|
+
disabled: !selectedId || isLoading,
|
|
59
|
+
className: "w-full h-10",
|
|
60
|
+
children: isLoading ? "Loading..." : "Continue"
|
|
61
|
+
}
|
|
62
|
+
)
|
|
63
|
+
] })
|
|
51
64
|
] }) });
|
|
52
65
|
}
|
|
53
66
|
|
|
@@ -65,13 +78,15 @@ function useLoginFlow(props) {
|
|
|
65
78
|
onSelectOrg,
|
|
66
79
|
onClearError,
|
|
67
80
|
onDiscover,
|
|
68
|
-
onExternalLogin
|
|
81
|
+
onExternalLogin,
|
|
82
|
+
requiresOrgSelection = true
|
|
69
83
|
} = props;
|
|
70
84
|
const navigate = useNavigate();
|
|
71
85
|
const location = useLocation();
|
|
72
86
|
const locationState = location.state;
|
|
73
87
|
const identifierFirst = Boolean(onDiscover);
|
|
74
|
-
const
|
|
88
|
+
const requestedStep = requiresOrgSelection && locationState?.step ? locationState.step : void 0;
|
|
89
|
+
const initial = requestedStep ?? (identifierFirst ? "identifier" : "credentials");
|
|
75
90
|
const [redirectTo] = useState2(() => locationState?.from?.pathname ?? "/");
|
|
76
91
|
const [step, setStep] = useState2(initial);
|
|
77
92
|
const [identifier, setIdentifier] = useState2("");
|
|
@@ -81,10 +96,17 @@ function useLoginFlow(props) {
|
|
|
81
96
|
const [isRedirecting, setIsRedirecting] = useState2(false);
|
|
82
97
|
const [orgError, setOrgError] = useState2(null);
|
|
83
98
|
useEffect(() => {
|
|
84
|
-
if (isAuthenticated && activeTenantId)
|
|
99
|
+
if (isAuthenticated && (activeTenantId || !requiresOrgSelection))
|
|
85
100
|
navigate(redirectTo, { replace: true });
|
|
86
|
-
}, [
|
|
101
|
+
}, [
|
|
102
|
+
isAuthenticated,
|
|
103
|
+
activeTenantId,
|
|
104
|
+
requiresOrgSelection,
|
|
105
|
+
navigate,
|
|
106
|
+
redirectTo
|
|
107
|
+
]);
|
|
87
108
|
useEffect(() => {
|
|
109
|
+
if (!requiresOrgSelection) return;
|
|
88
110
|
if (!isAuthenticated || !orgs || activeTenantId) return;
|
|
89
111
|
if (orgs.length === 1) {
|
|
90
112
|
onSelectOrg(orgs[0].id).catch((err) => {
|
|
@@ -96,7 +118,13 @@ function useLoginFlow(props) {
|
|
|
96
118
|
} else if (orgs.length > 1) {
|
|
97
119
|
setStep("org-selection");
|
|
98
120
|
}
|
|
99
|
-
}, [
|
|
121
|
+
}, [
|
|
122
|
+
requiresOrgSelection,
|
|
123
|
+
isAuthenticated,
|
|
124
|
+
orgs,
|
|
125
|
+
activeTenantId,
|
|
126
|
+
onSelectOrg
|
|
127
|
+
]);
|
|
100
128
|
useEffect(() => {
|
|
101
129
|
if (config?.ui.direct_redirect)
|
|
102
130
|
window.location.href = config.ui.direct_redirect;
|
|
@@ -178,19 +206,47 @@ function useLoginFlow(props) {
|
|
|
178
206
|
goBack
|
|
179
207
|
};
|
|
180
208
|
}
|
|
209
|
+
function resolveScreen(args) {
|
|
210
|
+
if (args.directRedirect || args.isRedirecting) return "redirecting";
|
|
211
|
+
const canShowOrgPicker = args.requiresOrgSelection && args.step === "org-selection" && args.orgsLoaded;
|
|
212
|
+
if (args.isAuthenticated && !args.activeTenantId && !canShowOrgPicker)
|
|
213
|
+
return "redirecting";
|
|
214
|
+
return canShowOrgPicker ? "org-selection" : "form";
|
|
215
|
+
}
|
|
181
216
|
function Login(props) {
|
|
182
|
-
const {
|
|
217
|
+
const {
|
|
218
|
+
config,
|
|
219
|
+
isAuthenticated,
|
|
220
|
+
activeTenantId,
|
|
221
|
+
isLoading,
|
|
222
|
+
isDiscovering,
|
|
223
|
+
error,
|
|
224
|
+
orgs,
|
|
225
|
+
appName,
|
|
226
|
+
logoUrl,
|
|
227
|
+
orgEmptyAction,
|
|
228
|
+
requiresOrgSelection = true
|
|
229
|
+
} = props;
|
|
183
230
|
const flow = useLoginFlow(props);
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
231
|
+
const screen = resolveScreen({
|
|
232
|
+
isRedirecting: flow.isRedirecting,
|
|
233
|
+
directRedirect: Boolean(config?.ui.direct_redirect),
|
|
234
|
+
isAuthenticated,
|
|
235
|
+
activeTenantId,
|
|
236
|
+
requiresOrgSelection,
|
|
237
|
+
step: flow.step,
|
|
238
|
+
orgsLoaded: orgs !== null
|
|
239
|
+
});
|
|
240
|
+
if (screen === "redirecting") return /* @__PURE__ */ jsx2(RedirectingMessage, {});
|
|
241
|
+
if (screen === "org-selection") {
|
|
187
242
|
return /* @__PURE__ */ jsx2(
|
|
188
243
|
OrgSelection,
|
|
189
244
|
{
|
|
190
|
-
orgs,
|
|
245
|
+
orgs: orgs ?? [],
|
|
191
246
|
isLoading,
|
|
192
247
|
error: flow.orgError,
|
|
193
|
-
onSelect: flow.handleOrgSelect
|
|
248
|
+
onSelect: flow.handleOrgSelect,
|
|
249
|
+
emptyAction: orgEmptyAction
|
|
194
250
|
}
|
|
195
251
|
);
|
|
196
252
|
}
|
|
@@ -242,26 +298,17 @@ function Login(props) {
|
|
|
242
298
|
] }) });
|
|
243
299
|
}
|
|
244
300
|
function PageShell({ children }) {
|
|
245
|
-
return /* @__PURE__ */ jsx2("div", { className: "flex flex-col items-center justify-center min-h-screen bg-
|
|
301
|
+
return /* @__PURE__ */ jsx2("div", { className: "flex flex-col items-center justify-center min-h-screen bg-muted px-4", children });
|
|
246
302
|
}
|
|
247
303
|
function Card({ children }) {
|
|
248
|
-
return /* @__PURE__ */ jsx2(
|
|
249
|
-
"div",
|
|
250
|
-
{
|
|
251
|
-
className: "w-full max-w-sm bg-white rounded-xl border border-gray-200 p-8",
|
|
252
|
-
style: {
|
|
253
|
-
boxShadow: "0 24px 48px rgba(15,23,42,0.10), 0 2px 4px rgba(15,23,42,0.06)"
|
|
254
|
-
},
|
|
255
|
-
children
|
|
256
|
-
}
|
|
257
|
-
);
|
|
304
|
+
return /* @__PURE__ */ jsx2("div", { className: "w-full max-w-sm bg-card rounded-lg border border-border shadow-sm p-8", children });
|
|
258
305
|
}
|
|
259
306
|
function BrandHeader({
|
|
260
307
|
appName,
|
|
261
308
|
logoUrl
|
|
262
309
|
}) {
|
|
263
310
|
if (!appName && !logoUrl) return null;
|
|
264
|
-
return /* @__PURE__ */ jsx2("div", { className: "flex flex-col items-center mb-6", children: logoUrl ? /* @__PURE__ */ jsx2("img", { src: logoUrl, alt: appName ?? "Logo", className: "h-10 w-auto" }) : /* @__PURE__ */ jsx2("span", { className: "text-lg font-semibold text-
|
|
311
|
+
return /* @__PURE__ */ jsx2("div", { className: "flex flex-col items-center mb-6", children: logoUrl ? /* @__PURE__ */ jsx2("img", { src: logoUrl, alt: appName ?? "Logo", className: "h-10 w-auto" }) : /* @__PURE__ */ jsx2("span", { className: "text-lg font-semibold text-muted-foreground tracking-wide", children: appName }) });
|
|
265
312
|
}
|
|
266
313
|
function IdentifierStep({
|
|
267
314
|
appName,
|
|
@@ -275,19 +322,12 @@ function IdentifierStep({
|
|
|
275
322
|
return /* @__PURE__ */ jsxs2("form", { onSubmit, className: "space-y-6", children: [
|
|
276
323
|
/* @__PURE__ */ jsx2(BrandHeader, { appName, logoUrl }),
|
|
277
324
|
/* @__PURE__ */ jsxs2("div", { className: "text-center", children: [
|
|
278
|
-
/* @__PURE__ */ jsx2("h1", { className: "text-2xl font-semibold text-
|
|
279
|
-
/* @__PURE__ */ jsx2("p", { className: "mt-2 text-sm text-
|
|
325
|
+
/* @__PURE__ */ jsx2("h1", { className: "text-2xl font-semibold text-foreground leading-tight", children: "Welcome" }),
|
|
326
|
+
/* @__PURE__ */ jsx2("p", { className: "mt-2 text-sm text-muted-foreground", children: "Enter your email or username to continue." })
|
|
280
327
|
] }),
|
|
281
328
|
error ? /* @__PURE__ */ jsx2(ErrorAlert, { message: error }) : null,
|
|
282
329
|
/* @__PURE__ */ jsxs2("div", { children: [
|
|
283
|
-
/* @__PURE__ */ jsx2(
|
|
284
|
-
Label,
|
|
285
|
-
{
|
|
286
|
-
htmlFor: "identifier",
|
|
287
|
-
className: "block text-sm font-medium text-gray-700 mb-1.5",
|
|
288
|
-
children: "Email or username"
|
|
289
|
-
}
|
|
290
|
-
),
|
|
330
|
+
/* @__PURE__ */ jsx2(Label, { htmlFor: "identifier", className: "mb-1.5 block", children: "Email or username" }),
|
|
291
331
|
/* @__PURE__ */ jsx2(
|
|
292
332
|
Input,
|
|
293
333
|
{
|
|
@@ -298,8 +338,7 @@ function IdentifierStep({
|
|
|
298
338
|
required: true,
|
|
299
339
|
autoFocus: true,
|
|
300
340
|
autoComplete: "email",
|
|
301
|
-
placeholder: "you@company.com"
|
|
302
|
-
className: "h-10 rounded-lg border-gray-300 text-sm placeholder:text-gray-400 focus:ring-indigo-500 focus:border-indigo-500"
|
|
341
|
+
placeholder: "you@company.com"
|
|
303
342
|
}
|
|
304
343
|
)
|
|
305
344
|
] }),
|
|
@@ -339,27 +378,20 @@ function AuthStep({
|
|
|
339
378
|
{
|
|
340
379
|
type: "button",
|
|
341
380
|
onClick: onBack,
|
|
342
|
-
className: "flex items-center gap-1.5 text-sm text-
|
|
381
|
+
className: "flex items-center gap-1.5 text-sm text-muted-foreground hover:text-foreground transition-colors mb-4",
|
|
343
382
|
children: [
|
|
344
383
|
/* @__PURE__ */ jsx2("span", { "aria-hidden": true, children: "\u2190" }),
|
|
345
384
|
" Back"
|
|
346
385
|
]
|
|
347
386
|
}
|
|
348
387
|
),
|
|
349
|
-
/* @__PURE__ */ jsx2("h1", { className: "text-2xl font-semibold text-
|
|
350
|
-
/* @__PURE__ */ jsx2("p", { className: "mt-1 text-sm text-
|
|
388
|
+
/* @__PURE__ */ jsx2("h1", { className: "text-2xl font-semibold text-foreground leading-tight", children: "Welcome back" }),
|
|
389
|
+
/* @__PURE__ */ jsx2("p", { className: "mt-1 text-sm text-muted-foreground", children: identifier })
|
|
351
390
|
] }),
|
|
352
391
|
error ? /* @__PURE__ */ jsx2(ErrorAlert, { message: error }) : null,
|
|
353
392
|
hasLocal ? /* @__PURE__ */ jsxs2("form", { onSubmit: onCredentialSubmit, className: "space-y-4", children: [
|
|
354
393
|
/* @__PURE__ */ jsxs2("div", { children: [
|
|
355
|
-
/* @__PURE__ */ jsx2(
|
|
356
|
-
Label,
|
|
357
|
-
{
|
|
358
|
-
htmlFor: "password",
|
|
359
|
-
className: "block text-sm font-medium text-gray-700 mb-1.5",
|
|
360
|
-
children: "Password"
|
|
361
|
-
}
|
|
362
|
-
),
|
|
394
|
+
/* @__PURE__ */ jsx2(Label, { htmlFor: "password", className: "mb-1.5 block", children: "Password" }),
|
|
363
395
|
/* @__PURE__ */ jsx2(
|
|
364
396
|
Input,
|
|
365
397
|
{
|
|
@@ -370,8 +402,7 @@ function AuthStep({
|
|
|
370
402
|
required: true,
|
|
371
403
|
autoFocus: true,
|
|
372
404
|
autoComplete: "current-password",
|
|
373
|
-
placeholder: "Enter your password"
|
|
374
|
-
className: "h-10 rounded-lg border-gray-300 text-sm placeholder:text-gray-400 focus:ring-indigo-500 focus:border-indigo-500"
|
|
405
|
+
placeholder: "Enter your password"
|
|
375
406
|
}
|
|
376
407
|
)
|
|
377
408
|
] }),
|
|
@@ -395,7 +426,7 @@ function AuthStep({
|
|
|
395
426
|
},
|
|
396
427
|
p.name
|
|
397
428
|
)) }) : null,
|
|
398
|
-
providers.length === 0 ? /* @__PURE__ */ jsx2("p", { className: "text-sm text-
|
|
429
|
+
providers.length === 0 ? /* @__PURE__ */ jsx2("p", { className: "text-sm text-muted-foreground text-center py-2", children: "No login methods available." }) : null
|
|
399
430
|
] });
|
|
400
431
|
}
|
|
401
432
|
function resolveOAuthProviders(config) {
|
|
@@ -418,18 +449,11 @@ function CredentialsStep({
|
|
|
418
449
|
const hasBoth = config?.features.local_auth && oauthProviders.length > 0;
|
|
419
450
|
return /* @__PURE__ */ jsxs2("div", { className: "space-y-6", children: [
|
|
420
451
|
/* @__PURE__ */ jsx2(BrandHeader, { appName, logoUrl }),
|
|
421
|
-
/* @__PURE__ */ jsx2("h1", { className: "text-2xl font-semibold text-
|
|
452
|
+
/* @__PURE__ */ jsx2("h1", { className: "text-2xl font-semibold text-foreground leading-tight text-center", children: "Welcome" }),
|
|
422
453
|
error ? /* @__PURE__ */ jsx2(ErrorAlert, { message: error }) : null,
|
|
423
454
|
config?.features.local_auth ? /* @__PURE__ */ jsxs2("form", { onSubmit, className: "space-y-4", children: [
|
|
424
455
|
/* @__PURE__ */ jsxs2("div", { children: [
|
|
425
|
-
/* @__PURE__ */ jsx2(
|
|
426
|
-
Label,
|
|
427
|
-
{
|
|
428
|
-
htmlFor: "identifier",
|
|
429
|
-
className: "block text-sm font-medium text-gray-700 mb-1.5",
|
|
430
|
-
children: "Email or username"
|
|
431
|
-
}
|
|
432
|
-
),
|
|
456
|
+
/* @__PURE__ */ jsx2(Label, { htmlFor: "identifier", className: "mb-1.5 block", children: "Email or username" }),
|
|
433
457
|
/* @__PURE__ */ jsx2(
|
|
434
458
|
Input,
|
|
435
459
|
{
|
|
@@ -440,20 +464,12 @@ function CredentialsStep({
|
|
|
440
464
|
required: true,
|
|
441
465
|
autoFocus: true,
|
|
442
466
|
autoComplete: "email",
|
|
443
|
-
placeholder: "you@company.com"
|
|
444
|
-
className: "h-10 rounded-lg border-gray-300 text-sm placeholder:text-gray-400 focus:ring-indigo-500 focus:border-indigo-500"
|
|
467
|
+
placeholder: "you@company.com"
|
|
445
468
|
}
|
|
446
469
|
)
|
|
447
470
|
] }),
|
|
448
471
|
/* @__PURE__ */ jsxs2("div", { children: [
|
|
449
|
-
/* @__PURE__ */ jsx2(
|
|
450
|
-
Label,
|
|
451
|
-
{
|
|
452
|
-
htmlFor: "password",
|
|
453
|
-
className: "block text-sm font-medium text-gray-700 mb-1.5",
|
|
454
|
-
children: "Password"
|
|
455
|
-
}
|
|
456
|
-
),
|
|
472
|
+
/* @__PURE__ */ jsx2(Label, { htmlFor: "password", className: "mb-1.5 block", children: "Password" }),
|
|
457
473
|
/* @__PURE__ */ jsx2(
|
|
458
474
|
Input,
|
|
459
475
|
{
|
|
@@ -463,8 +479,7 @@ function CredentialsStep({
|
|
|
463
479
|
onChange: (e) => onPasswordChange(e.target.value),
|
|
464
480
|
required: true,
|
|
465
481
|
autoComplete: "current-password",
|
|
466
|
-
placeholder: "Enter your password"
|
|
467
|
-
className: "h-10 rounded-lg border-gray-300 text-sm placeholder:text-gray-400 focus:ring-indigo-500 focus:border-indigo-500"
|
|
482
|
+
placeholder: "Enter your password"
|
|
468
483
|
}
|
|
469
484
|
)
|
|
470
485
|
] }),
|
|
@@ -491,18 +506,25 @@ function CredentialsStep({
|
|
|
491
506
|
] });
|
|
492
507
|
}
|
|
493
508
|
function RedirectingMessage() {
|
|
494
|
-
return /* @__PURE__ */ jsxs2("div", { className: "flex flex-col items-center justify-center min-h-screen bg-
|
|
509
|
+
return /* @__PURE__ */ jsxs2("div", { className: "flex flex-col items-center justify-center min-h-screen bg-muted gap-3 text-muted-foreground", children: [
|
|
495
510
|
/* @__PURE__ */ jsx2(Spinner, { size: "lg" }),
|
|
496
511
|
/* @__PURE__ */ jsx2("p", { className: "text-sm", children: "Redirecting..." })
|
|
497
512
|
] });
|
|
498
513
|
}
|
|
499
514
|
function ErrorAlert({ message }) {
|
|
500
|
-
return /* @__PURE__ */ jsx2(
|
|
515
|
+
return /* @__PURE__ */ jsx2(
|
|
516
|
+
Alert2,
|
|
517
|
+
{
|
|
518
|
+
variant: "destructive",
|
|
519
|
+
className: "bg-destructive/10 px-3 py-2.5 text-sm",
|
|
520
|
+
children: message
|
|
521
|
+
}
|
|
522
|
+
);
|
|
501
523
|
}
|
|
502
524
|
function Separator() {
|
|
503
525
|
return /* @__PURE__ */ jsxs2("div", { className: "relative", children: [
|
|
504
|
-
/* @__PURE__ */ jsx2("div", { className: "absolute inset-0 flex items-center", children: /* @__PURE__ */ jsx2("div", { className: "w-full border-t border-
|
|
505
|
-
/* @__PURE__ */ jsx2("div", { className: "relative flex justify-center text-xs", children: /* @__PURE__ */ jsx2("span", { className: "bg-
|
|
526
|
+
/* @__PURE__ */ jsx2("div", { className: "absolute inset-0 flex items-center", children: /* @__PURE__ */ jsx2("div", { className: "w-full border-t border-border" }) }),
|
|
527
|
+
/* @__PURE__ */ jsx2("div", { className: "relative flex justify-center text-xs", children: /* @__PURE__ */ jsx2("span", { className: "bg-card px-2 text-muted-foreground", children: "or continue with" }) })
|
|
506
528
|
] });
|
|
507
529
|
}
|
|
508
530
|
function PrimaryButton({
|
|
@@ -514,17 +536,15 @@ function PrimaryButton({
|
|
|
514
536
|
onClick
|
|
515
537
|
}) {
|
|
516
538
|
return /* @__PURE__ */ jsxs2(
|
|
517
|
-
|
|
539
|
+
Button2,
|
|
518
540
|
{
|
|
519
541
|
type,
|
|
542
|
+
size: "lg",
|
|
520
543
|
disabled,
|
|
521
544
|
onClick,
|
|
522
|
-
className: "w-full
|
|
523
|
-
style: {
|
|
524
|
-
boxShadow: disabled ? void 0 : "0 4px 14px rgba(79,70,229,0.30)"
|
|
525
|
-
},
|
|
545
|
+
className: "w-full",
|
|
526
546
|
children: [
|
|
527
|
-
loading ? /* @__PURE__ */ jsx2(Spinner, { size: "sm"
|
|
547
|
+
loading ? /* @__PURE__ */ jsx2(Spinner, { size: "sm" }) : null,
|
|
528
548
|
loading && loadingText ? loadingText : children
|
|
529
549
|
]
|
|
530
550
|
}
|
|
@@ -532,11 +552,13 @@ function PrimaryButton({
|
|
|
532
552
|
}
|
|
533
553
|
function SsoButton({ label, onClick }) {
|
|
534
554
|
return /* @__PURE__ */ jsx2(
|
|
535
|
-
|
|
555
|
+
Button2,
|
|
536
556
|
{
|
|
537
557
|
type: "button",
|
|
558
|
+
variant: "outline",
|
|
559
|
+
size: "lg",
|
|
538
560
|
onClick,
|
|
539
|
-
className: "w-full
|
|
561
|
+
className: "w-full",
|
|
540
562
|
children: label
|
|
541
563
|
}
|
|
542
564
|
);
|
|
@@ -546,7 +568,7 @@ function SsoButton({ label, onClick }) {
|
|
|
546
568
|
import { Navigate, useLocation as useLocation2 } from "react-router-dom";
|
|
547
569
|
import { useEffect as useEffect2, useRef, useState as useState3 } from "react";
|
|
548
570
|
import { Spinner as Spinner2 } from "@petrarca/sonnet-ui";
|
|
549
|
-
import { Fragment, jsx as jsx3 } from "react/jsx-runtime";
|
|
571
|
+
import { Fragment as Fragment2, jsx as jsx3 } from "react/jsx-runtime";
|
|
550
572
|
function ProtectedRoute({
|
|
551
573
|
children,
|
|
552
574
|
authEnabled,
|
|
@@ -554,7 +576,8 @@ function ProtectedRoute({
|
|
|
554
576
|
isAuthenticated,
|
|
555
577
|
accessToken,
|
|
556
578
|
activeTenantId,
|
|
557
|
-
initializeAuth
|
|
579
|
+
initializeAuth,
|
|
580
|
+
requiresOrgSelection = true
|
|
558
581
|
}) {
|
|
559
582
|
const location = useLocation2();
|
|
560
583
|
const [initializing, setInitializing] = useState3(true);
|
|
@@ -566,7 +589,7 @@ function ProtectedRoute({
|
|
|
566
589
|
return /* @__PURE__ */ jsx3("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsx3(Spinner2, { size: "lg" }) });
|
|
567
590
|
}
|
|
568
591
|
if (!authEnabled) {
|
|
569
|
-
return /* @__PURE__ */ jsx3(
|
|
592
|
+
return /* @__PURE__ */ jsx3(Fragment2, { children });
|
|
570
593
|
}
|
|
571
594
|
if (!isAuthenticated || !accessToken) {
|
|
572
595
|
return /* @__PURE__ */ jsx3(
|
|
@@ -578,17 +601,17 @@ function ProtectedRoute({
|
|
|
578
601
|
}
|
|
579
602
|
);
|
|
580
603
|
}
|
|
581
|
-
if (!activeTenantId) {
|
|
604
|
+
if (requiresOrgSelection && !activeTenantId) {
|
|
582
605
|
return /* @__PURE__ */ jsx3(
|
|
583
606
|
Navigate,
|
|
584
607
|
{
|
|
585
608
|
to: "/login",
|
|
586
|
-
state: { from: location, step: "
|
|
609
|
+
state: { from: location, step: "org-selection" },
|
|
587
610
|
replace: true
|
|
588
611
|
}
|
|
589
612
|
);
|
|
590
613
|
}
|
|
591
|
-
return /* @__PURE__ */ jsx3(
|
|
614
|
+
return /* @__PURE__ */ jsx3(Fragment2, { children });
|
|
592
615
|
}
|
|
593
616
|
export {
|
|
594
617
|
Login,
|