@omnibase/shadcn 0.4.2 → 0.5.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/index.cjs CHANGED
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  "use strict";
2
3
  var __create = Object.create;
3
4
  var __defProp = Object.defineProperty;
@@ -30,10 +31,23 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
31
  // src/index.ts
31
32
  var index_exports = {};
32
33
  __export(index_exports, {
33
- CustomFlowForm: () => CustomFlowForm,
34
+ LoginForm: () => LoginForm,
34
35
  PricingTable: () => PricingTable,
36
+ RecoveryForm: () => RecoveryForm,
37
+ RegistrationForm: () => RegistrationForm,
38
+ RoleCreator: () => RoleCreator,
39
+ SettingsForm: () => SettingsForm,
35
40
  SwitchActiveTenant: () => SwitchActiveTenant,
36
- TenantCreator: () => TenantCreator
41
+ TenantCreator: () => TenantCreator,
42
+ UserInvite: () => UserInvite,
43
+ VerificationForm: () => VerificationForm,
44
+ filterInputNodes: () => filterInputNodes,
45
+ findAnchorNode: () => findAnchorNode,
46
+ findCsrfToken: () => findCsrfToken,
47
+ findSubmitButton: () => findSubmitButton,
48
+ groupNodesByGroup: () => groupNodesByGroup,
49
+ isUiNodeInputAttributes: () => isUiNodeInputAttributes,
50
+ sortNodes: () => sortNodes
37
51
  });
38
52
  module.exports = __toCommonJS(index_exports);
39
53
 
@@ -116,12 +130,131 @@ function CardFooter({ className, ...props }) {
116
130
  );
117
131
  }
118
132
 
119
- // src/components/ui/button.tsx
120
- var React2 = require("react");
121
- var import_react_slot = require("@radix-ui/react-slot");
133
+ // src/components/ui/messages.tsx
134
+ var React3 = __toESM(require("react"), 1);
135
+
136
+ // src/components/ui/alert.tsx
137
+ var React2 = __toESM(require("react"), 1);
122
138
  var import_class_variance_authority = require("class-variance-authority");
123
139
  var import_jsx_runtime2 = require("react/jsx-runtime");
124
- var buttonVariants = (0, import_class_variance_authority.cva)(
140
+ var alertVariants = (0, import_class_variance_authority.cva)(
141
+ "relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7",
142
+ {
143
+ variants: {
144
+ variant: {
145
+ default: "bg-background text-foreground",
146
+ destructive: "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
147
+ warning: "border-yellow-500/50 text-yellow-700 bg-yellow-50 dark:border-yellow-500 dark:text-yellow-200 dark:bg-yellow-950/20 [&>svg]:text-yellow-600 dark:[&>svg]:text-yellow-200",
148
+ success: "border-green-500/50 text-green-700 bg-green-50 dark:border-green-500 dark:text-green-200 dark:bg-green-950/20 [&>svg]:text-green-600 dark:[&>svg]:text-green-200",
149
+ info: "border-blue-500/50 text-blue-700 bg-blue-50 dark:border-blue-500 dark:text-blue-200 dark:bg-blue-950/20 [&>svg]:text-blue-600 dark:[&>svg]:text-blue-200"
150
+ }
151
+ },
152
+ defaultVariants: {
153
+ variant: "default"
154
+ }
155
+ }
156
+ );
157
+ var Alert = React2.forwardRef(({ className, variant, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
158
+ "div",
159
+ {
160
+ ref,
161
+ role: "alert",
162
+ className: cn(alertVariants({ variant }), className),
163
+ ...props
164
+ }
165
+ ));
166
+ Alert.displayName = "Alert";
167
+ var AlertTitle = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
168
+ "h5",
169
+ {
170
+ ref,
171
+ className: cn("mb-1 font-medium leading-none tracking-tight", className),
172
+ ...props
173
+ }
174
+ ));
175
+ AlertTitle.displayName = "AlertTitle";
176
+ var AlertDescription = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
177
+ "div",
178
+ {
179
+ ref,
180
+ className: cn("text-sm [&_p]:leading-relaxed", className),
181
+ ...props
182
+ }
183
+ ));
184
+ AlertDescription.displayName = "AlertDescription";
185
+
186
+ // src/components/ui/messages.tsx
187
+ var import_jsx_runtime3 = require("react/jsx-runtime");
188
+ var getMessageVariant = (type) => {
189
+ switch (type) {
190
+ case "error":
191
+ return "destructive";
192
+ case "success":
193
+ return "success";
194
+ case "info":
195
+ return "info";
196
+ case "11184809":
197
+ return "warning";
198
+ default:
199
+ return "default";
200
+ }
201
+ };
202
+ var Messages = React3.forwardRef(
203
+ ({ flow, className, ...props }, ref) => {
204
+ if (!flow?.ui) return null;
205
+ const allMessages = [];
206
+ if (flow.ui.messages) {
207
+ allMessages.push(...flow.ui.messages);
208
+ }
209
+ if (flow.ui.nodes) {
210
+ flow.ui.nodes.forEach((node) => {
211
+ if (node.messages) {
212
+ allMessages.push(...node.messages);
213
+ }
214
+ });
215
+ }
216
+ if (allMessages.length === 0) return null;
217
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
218
+ "div",
219
+ {
220
+ ref,
221
+ className: cn("w-full max-w-md mx-auto space-y-2 mb-4", className),
222
+ ...props,
223
+ children: allMessages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Alert, { variant: getMessageVariant(message.type), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AlertDescription, { children: message.text }) }, message.id))
224
+ }
225
+ );
226
+ }
227
+ );
228
+ Messages.displayName = "Messages";
229
+
230
+ // src/form/types.ts
231
+ function isUiNodeInputAttributes(attributes) {
232
+ return attributes && typeof attributes === "object" && "name" in attributes && "type" in attributes;
233
+ }
234
+
235
+ // src/form/components/HiddenInput.tsx
236
+ var import_jsx_runtime4 = require("react/jsx-runtime");
237
+ function HiddenInput({ node }) {
238
+ if (!isUiNodeInputAttributes(node.attributes)) {
239
+ return null;
240
+ }
241
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
242
+ "input",
243
+ {
244
+ name: node.attributes.name,
245
+ type: "hidden",
246
+ value: node.attributes.value || "",
247
+ readOnly: true
248
+ }
249
+ );
250
+ }
251
+
252
+ // src/components/ui/button.tsx
253
+ var React4 = require("react");
254
+ var import_react_slot = require("@radix-ui/react-slot");
255
+ var import_class_variance_authority2 = require("class-variance-authority");
256
+ var import_jsx_runtime5 = require("react/jsx-runtime");
257
+ var buttonVariants = (0, import_class_variance_authority2.cva)(
125
258
  "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
126
259
  {
127
260
  variants: {
@@ -154,7 +287,7 @@ function Button({
154
287
  ...props
155
288
  }) {
156
289
  const Comp = asChild ? import_react_slot.Slot : "button";
157
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
290
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
158
291
  Comp,
159
292
  {
160
293
  "data-slot": "button",
@@ -164,11 +297,78 @@ function Button({
164
297
  );
165
298
  }
166
299
 
300
+ // src/form/components/SubmitButton.tsx
301
+ var import_jsx_runtime6 = require("react/jsx-runtime");
302
+ function SubmitButton({
303
+ node,
304
+ variant = "default",
305
+ className = "w-full"
306
+ }) {
307
+ if (!isUiNodeInputAttributes(node.attributes)) {
308
+ return null;
309
+ }
310
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
311
+ Button,
312
+ {
313
+ type: "submit",
314
+ name: node.attributes.name,
315
+ value: node.attributes.value || "",
316
+ variant,
317
+ className,
318
+ disabled: node.attributes.disabled,
319
+ children: node.meta.label?.text || node.attributes.value || "Submit"
320
+ }
321
+ );
322
+ }
323
+
324
+ // src/form/components/Divider.tsx
325
+ var import_jsx_runtime7 = require("react/jsx-runtime");
326
+ function Divider({ withText = false }) {
327
+ if (withText) {
328
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "relative my-6", children: [
329
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "absolute inset-0 flex items-center", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "w-full border-t border-border" }) }),
330
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "relative flex justify-center text-xs uppercase", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "bg-background px-3 text-muted-foreground font-medium", children: "Or continue with" }) })
331
+ ] });
332
+ }
333
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "border-t border-border my-6" });
334
+ }
335
+
336
+ // src/form/components/OidcGroup.tsx
337
+ var import_jsx_runtime8 = require("react/jsx-runtime");
338
+ function OidcGroup({
339
+ nodes,
340
+ flowAction,
341
+ flowMethod,
342
+ csrfToken,
343
+ groupIndex,
344
+ groupName
345
+ }) {
346
+ const submitButtons = nodes.filter(
347
+ (node) => isUiNodeInputAttributes(node.attributes) && node.attributes.type === "submit"
348
+ );
349
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
350
+ groupIndex > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Divider, { withText: true }),
351
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "space-y-3", children: submitButtons.map((node, btnIndex) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
352
+ "form",
353
+ {
354
+ action: flowAction,
355
+ method: flowMethod,
356
+ className: "w-full",
357
+ children: [
358
+ csrfToken && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(HiddenInput, { node: csrfToken }),
359
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SubmitButton, { node, variant: "outline" })
360
+ ]
361
+ },
362
+ `${groupName}-${btnIndex}`
363
+ )) })
364
+ ] });
365
+ }
366
+
167
367
  // src/components/ui/input.tsx
168
- var React3 = require("react");
169
- var import_jsx_runtime3 = require("react/jsx-runtime");
368
+ var React5 = require("react");
369
+ var import_jsx_runtime9 = require("react/jsx-runtime");
170
370
  function Input({ className, type, ...props }) {
171
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
371
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
172
372
  "input",
173
373
  {
174
374
  type,
@@ -185,14 +385,14 @@ function Input({ className, type, ...props }) {
185
385
  }
186
386
 
187
387
  // src/components/ui/label.tsx
188
- var React4 = require("react");
388
+ var React6 = require("react");
189
389
  var LabelPrimitive = __toESM(require("@radix-ui/react-label"), 1);
190
- var import_jsx_runtime4 = require("react/jsx-runtime");
390
+ var import_jsx_runtime10 = require("react/jsx-runtime");
191
391
  function Label({
192
392
  className,
193
393
  ...props
194
394
  }) {
195
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
395
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
196
396
  LabelPrimitive.Root,
197
397
  {
198
398
  "data-slot": "label",
@@ -205,109 +405,393 @@ function Label({
205
405
  );
206
406
  }
207
407
 
208
- // src/components/ui/messages.tsx
209
- var React6 = __toESM(require("react"), 1);
210
-
211
- // src/components/ui/alert.tsx
212
- var React5 = __toESM(require("react"), 1);
213
- var import_class_variance_authority2 = require("class-variance-authority");
214
- var import_jsx_runtime5 = require("react/jsx-runtime");
215
- var alertVariants = (0, import_class_variance_authority2.cva)(
216
- "relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7",
217
- {
218
- variants: {
219
- variant: {
220
- default: "bg-background text-foreground",
221
- destructive: "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
222
- warning: "border-yellow-500/50 text-yellow-700 bg-yellow-50 dark:border-yellow-500 dark:text-yellow-200 dark:bg-yellow-950/20 [&>svg]:text-yellow-600 dark:[&>svg]:text-yellow-200",
223
- success: "border-green-500/50 text-green-700 bg-green-50 dark:border-green-500 dark:text-green-200 dark:bg-green-950/20 [&>svg]:text-green-600 dark:[&>svg]:text-green-200",
224
- info: "border-blue-500/50 text-blue-700 bg-blue-50 dark:border-blue-500 dark:text-blue-200 dark:bg-blue-950/20 [&>svg]:text-blue-600 dark:[&>svg]:text-blue-200"
408
+ // src/form/components/FormInput.tsx
409
+ var import_jsx_runtime11 = require("react/jsx-runtime");
410
+ function FormInput({ node }) {
411
+ if (!isUiNodeInputAttributes(node.attributes)) {
412
+ return null;
413
+ }
414
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "space-y-2", children: [
415
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Label, { htmlFor: node.attributes.name, children: [
416
+ node.meta.label?.text,
417
+ node.attributes.required && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-destructive ml-1", children: "*" })
418
+ ] }),
419
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
420
+ Input,
421
+ {
422
+ id: node.attributes.name,
423
+ name: node.attributes.name,
424
+ type: node.attributes.type,
425
+ defaultValue: node.attributes.value || "",
426
+ required: node.attributes.required,
427
+ disabled: node.attributes.disabled,
428
+ autoComplete: node.attributes.autocomplete,
429
+ placeholder: `Enter your ${node.meta.label?.text?.toLowerCase() || node.attributes.name}`
225
430
  }
226
- },
227
- defaultVariants: {
228
- variant: "default"
431
+ )
432
+ ] });
433
+ }
434
+
435
+ // src/form/utils.ts
436
+ var TYPE_ORDER = {
437
+ hidden: 0,
438
+ text: 1,
439
+ email: 1,
440
+ password: 1,
441
+ checkbox: 1,
442
+ submit: 2
443
+ };
444
+ function sortNodes(nodes) {
445
+ return [...nodes].sort((a, b) => {
446
+ const aIsInput = isUiNodeInputAttributes(a.attributes);
447
+ const bIsInput = isUiNodeInputAttributes(b.attributes);
448
+ if (!aIsInput && !bIsInput) return 0;
449
+ if (!aIsInput) return 1;
450
+ if (!bIsInput) return -1;
451
+ const aAttrs = a.attributes;
452
+ const bAttrs = b.attributes;
453
+ const aOrder = TYPE_ORDER[aAttrs.type] ?? 1;
454
+ const bOrder = TYPE_ORDER[bAttrs.type] ?? 1;
455
+ return aOrder - bOrder;
456
+ });
457
+ }
458
+ function findSubmitButton(nodes) {
459
+ return nodes.find(
460
+ (node) => isUiNodeInputAttributes(node.attributes) && node.attributes.type === "submit"
461
+ );
462
+ }
463
+ function findAnchorNode(nodes) {
464
+ return nodes.find((node) => node.type === "a");
465
+ }
466
+ function filterInputNodes(nodes) {
467
+ return nodes.filter(
468
+ (node) => isUiNodeInputAttributes(node.attributes) && node.attributes.type !== "submit" && node.attributes.type !== "hidden"
469
+ );
470
+ }
471
+ function findCsrfToken(nodes) {
472
+ return nodes.find(
473
+ (node) => isUiNodeInputAttributes(node.attributes) && node.attributes.name === "csrf_token"
474
+ );
475
+ }
476
+ function groupNodesByGroup(nodes) {
477
+ return nodes.reduce((groups, node) => {
478
+ const group = node.group || "default";
479
+ if (!groups[group]) {
480
+ groups[group] = [];
229
481
  }
230
- }
231
- );
232
- var Alert = React5.forwardRef(({ className, variant, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
233
- "div",
234
- {
235
- ref,
236
- role: "alert",
237
- className: cn(alertVariants({ variant }), className),
238
- ...props
239
- }
240
- ));
241
- Alert.displayName = "Alert";
242
- var AlertTitle = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
243
- "h5",
244
- {
245
- ref,
246
- className: cn("mb-1 font-medium leading-none tracking-tight", className),
247
- ...props
248
- }
249
- ));
250
- AlertTitle.displayName = "AlertTitle";
251
- var AlertDescription = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
252
- "div",
253
- {
254
- ref,
255
- className: cn("text-sm [&_p]:leading-relaxed", className),
256
- ...props
257
- }
258
- ));
259
- AlertDescription.displayName = "AlertDescription";
482
+ groups[group].push(node);
483
+ return groups;
484
+ }, {});
485
+ }
260
486
 
261
- // src/components/ui/messages.tsx
262
- var import_jsx_runtime6 = require("react/jsx-runtime");
263
- var getMessageVariant = (type) => {
264
- switch (type) {
265
- case "error":
266
- return "destructive";
267
- case "success":
268
- return "success";
269
- case "info":
270
- return "info";
271
- case "11184809":
272
- return "warning";
273
- default:
274
- return "default";
487
+ // src/form/login.tsx
488
+ var import_jsx_runtime12 = require("react/jsx-runtime");
489
+ function LoginForm({ flow, Header, register_url }) {
490
+ const nodesByGroup = groupNodesByGroup(flow.ui.nodes);
491
+ const csrfToken = findCsrfToken(flow.ui.nodes);
492
+ const oidcNodes = nodesByGroup.oidc || [];
493
+ const defaultNodes = nodesByGroup.default || [];
494
+ const passwordNodes = nodesByGroup.password || [];
495
+ const identifierNodes = filterInputNodes(sortNodes(defaultNodes));
496
+ const passwordInputNodes = filterInputNodes(sortNodes(passwordNodes));
497
+ const submitButton = findSubmitButton(sortNodes(passwordNodes));
498
+ const registerHref = register_url && flow.return_to ? `${register_url}?return_to=${encodeURIComponent(flow.return_to)}` : register_url;
499
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
500
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Messages, { flow }),
501
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Card, { className: "w-full max-w-md mx-auto", children: [
502
+ Header && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CardHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CardTitle, { className: "text-center pb-1", children: Header }) }),
503
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(CardContent, { className: "space-y-6", children: [
504
+ oidcNodes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
505
+ OidcGroup,
506
+ {
507
+ nodes: sortNodes(oidcNodes),
508
+ flowAction: flow.ui.action,
509
+ flowMethod: flow.ui.method,
510
+ csrfToken,
511
+ groupIndex: 0,
512
+ groupName: "oidc"
513
+ }
514
+ ),
515
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
516
+ oidcNodes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Divider, { withText: true }),
517
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("form", { action: flow.ui.action, method: flow.ui.method, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "space-y-4", children: [
518
+ csrfToken && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(HiddenInput, { node: csrfToken }),
519
+ identifierNodes.map((node, idx) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(FormInput, { node }, idx)),
520
+ passwordInputNodes.map((node, idx) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(FormInput, { node }, idx)),
521
+ submitButton && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SubmitButton, { node: submitButton })
522
+ ] }) }),
523
+ register_url && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "mt-4 text-center text-sm", children: [
524
+ "Don't have an account?",
525
+ " ",
526
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
527
+ "a",
528
+ {
529
+ href: registerHref,
530
+ className: "text-primary underline-offset-4 hover:underline",
531
+ children: "Go to Register"
532
+ }
533
+ )
534
+ ] })
535
+ ] })
536
+ ] })
537
+ ] })
538
+ ] });
539
+ }
540
+
541
+ // src/form/registration.tsx
542
+ var import_jsx_runtime13 = require("react/jsx-runtime");
543
+ function RegistrationForm({
544
+ flow,
545
+ Header,
546
+ login_url
547
+ }) {
548
+ const nodesByGroup = groupNodesByGroup(flow.ui.nodes);
549
+ const csrfToken = findCsrfToken(flow.ui.nodes);
550
+ const oidcNodes = nodesByGroup.oidc || [];
551
+ const defaultNodes = nodesByGroup.default || [];
552
+ const profileNodes = nodesByGroup.profile || [];
553
+ const passwordNodes = nodesByGroup.password || [];
554
+ const inputNodes = filterInputNodes(
555
+ sortNodes([...defaultNodes, ...passwordNodes])
556
+ );
557
+ const hiddenNodes = [...defaultNodes, ...passwordNodes].filter(
558
+ (node) => isUiNodeInputAttributes(node.attributes) && node.attributes.type === "hidden" && node.attributes.name !== "csrf_token"
559
+ );
560
+ const submitButton = findSubmitButton(sortNodes(passwordNodes)) || findSubmitButton(sortNodes(profileNodes));
561
+ const loginHref = login_url && flow.return_to ? `${login_url}?return_to=${encodeURIComponent(flow.return_to)}` : login_url;
562
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
563
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Messages, { flow }),
564
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Card, { className: "w-full max-w-md mx-auto", children: [
565
+ Header && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CardHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CardTitle, { className: "text-center pb-1", children: Header }) }),
566
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(CardContent, { className: "space-y-6", children: [
567
+ oidcNodes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
568
+ OidcGroup,
569
+ {
570
+ nodes: sortNodes(oidcNodes),
571
+ flowAction: flow.ui.action,
572
+ flowMethod: flow.ui.method,
573
+ csrfToken,
574
+ groupIndex: 0,
575
+ groupName: "oidc"
576
+ }
577
+ ),
578
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
579
+ oidcNodes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Divider, { withText: true }),
580
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("form", { action: flow.ui.action, method: flow.ui.method, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "space-y-4", children: [
581
+ csrfToken && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(HiddenInput, { node: csrfToken }),
582
+ hiddenNodes.map((node, idx) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(HiddenInput, { node }, `hidden-${idx}`)),
583
+ inputNodes.map((node, idx) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(FormInput, { node }, idx)),
584
+ submitButton && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SubmitButton, { node: submitButton })
585
+ ] }) }),
586
+ login_url && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "mt-4 text-center text-sm", children: [
587
+ "Already have an account?",
588
+ " ",
589
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
590
+ "a",
591
+ {
592
+ href: loginHref,
593
+ className: "text-primary underline-offset-4 hover:underline",
594
+ children: "Go to Login"
595
+ }
596
+ )
597
+ ] })
598
+ ] })
599
+ ] })
600
+ ] })
601
+ ] });
602
+ }
603
+
604
+ // src/form/verification.tsx
605
+ var React8 = __toESM(require("react"), 1);
606
+
607
+ // src/form/components/PinInput.tsx
608
+ var React7 = __toESM(require("react"), 1);
609
+ var import_jsx_runtime14 = require("react/jsx-runtime");
610
+ function PinInput({
611
+ node,
612
+ length = 6,
613
+ initialValue = ""
614
+ }) {
615
+ if (!isUiNodeInputAttributes(node.attributes)) {
616
+ return null;
275
617
  }
276
- };
277
- var Messages = React6.forwardRef(
278
- ({ flow, className, ...props }, ref) => {
279
- if (!flow?.ui) return null;
280
- const allMessages = [];
281
- if (flow.ui.messages) {
282
- allMessages.push(...flow.ui.messages);
618
+ const [pins, setPins] = React7.useState(() => {
619
+ if (initialValue) {
620
+ const sanitized = initialValue.replace(/[^0-9]/g, "").slice(0, length);
621
+ const pinArray = Array(length).fill("");
622
+ for (let i = 0; i < sanitized.length; i++) {
623
+ pinArray[i] = sanitized[i];
624
+ }
625
+ return pinArray;
283
626
  }
284
- if (flow.ui.nodes) {
285
- flow.ui.nodes.forEach((node) => {
286
- if (node.messages) {
287
- allMessages.push(...node.messages);
288
- }
289
- });
627
+ return Array(length).fill("");
628
+ });
629
+ const inputRefs = React7.useRef([]);
630
+ const handleChange = (index, value) => {
631
+ const sanitizedValue = value.replace(/[^0-9]/g, "").slice(0, 1);
632
+ const newPins = [...pins];
633
+ newPins[index] = sanitizedValue;
634
+ setPins(newPins);
635
+ if (sanitizedValue && index < length - 1) {
636
+ inputRefs.current[index + 1]?.focus();
290
637
  }
291
- if (allMessages.length === 0) return null;
292
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
293
- "div",
638
+ };
639
+ const handleKeyDown = (index, e) => {
640
+ if (e.key === "Backspace" && !pins[index] && index > 0) {
641
+ inputRefs.current[index - 1]?.focus();
642
+ }
643
+ if (e.key === "ArrowLeft" && index > 0) {
644
+ inputRefs.current[index - 1]?.focus();
645
+ }
646
+ if (e.key === "ArrowRight" && index < length - 1) {
647
+ inputRefs.current[index + 1]?.focus();
648
+ }
649
+ };
650
+ const handlePaste = (e) => {
651
+ e.preventDefault();
652
+ const pastedData = e.clipboardData.getData("text").replace(/[^0-9]/g, "");
653
+ const newPins = [...pins];
654
+ for (let i = 0; i < Math.min(pastedData.length, length); i++) {
655
+ newPins[i] = pastedData[i];
656
+ }
657
+ setPins(newPins);
658
+ const nextEmptyIndex = newPins.findIndex((pin) => !pin);
659
+ const focusIndex = nextEmptyIndex === -1 ? length - 1 : nextEmptyIndex;
660
+ inputRefs.current[focusIndex]?.focus();
661
+ };
662
+ const combinedValue = pins.join("");
663
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "space-y-2 mb-6", children: [
664
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "flex gap-2 justify-center", children: Array.from({ length }).map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
665
+ "input",
294
666
  {
295
- ref,
296
- className: cn("w-full max-w-md mx-auto space-y-2 mb-4", className),
297
- ...props,
298
- children: allMessages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Alert, { variant: getMessageVariant(message.type), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AlertDescription, { children: message.text }) }, message.id))
667
+ ref: (el) => inputRefs.current[index] = el,
668
+ type: "text",
669
+ inputMode: "numeric",
670
+ maxLength: 1,
671
+ value: pins[index],
672
+ onChange: (e) => handleChange(index, e.target.value),
673
+ onKeyDown: (e) => handleKeyDown(index, e),
674
+ onPaste: index === 0 ? handlePaste : void 0,
675
+ disabled: isUiNodeInputAttributes(node.attributes) ? node.attributes.disabled : false,
676
+ className: cn(
677
+ "w-10 h-12 text-center text-lg font-semibold rounded-md border-2",
678
+ "border-input bg-background shadow-sm transition-all duration-200 outline-none",
679
+ "hover:border-ring/60",
680
+ "focus:border-ring focus:ring-4 focus:ring-ring/20 focus:scale-105",
681
+ "aria-invalid:border-destructive aria-invalid:ring-destructive/20",
682
+ "disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
683
+ pins[index] && "border-primary bg-primary/5"
684
+ ),
685
+ "aria-label": `Digit ${index + 1}`
686
+ },
687
+ index
688
+ )) }),
689
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
690
+ "input",
691
+ {
692
+ type: "hidden",
693
+ id: node.attributes.name,
694
+ name: node.attributes.name,
695
+ value: combinedValue,
696
+ required: node.attributes.required
299
697
  }
300
- );
698
+ )
699
+ ] });
700
+ }
701
+
702
+ // src/form/components/AnchorButton.tsx
703
+ var import_jsx_runtime15 = require("react/jsx-runtime");
704
+ function AnchorButton({
705
+ node,
706
+ variant = "default",
707
+ className = "w-full"
708
+ }) {
709
+ if (node.type !== "a" || !("href" in node.attributes)) {
710
+ return null;
301
711
  }
302
- );
303
- Messages.displayName = "Messages";
712
+ const href = node.attributes.href;
713
+ const title = node.attributes.title;
714
+ const label = node.meta?.label;
715
+ const buttonText = (typeof title === "object" && title !== null && "text" in title ? title.text : typeof title === "string" ? title : null) || (label && typeof label === "object" && "text" in label ? label.text : null) || "Continue";
716
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { variant, className, asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("a", { href, children: buttonText }) });
717
+ }
304
718
 
305
- // src/form/index.tsx
306
- var import_jsx_runtime7 = require("react/jsx-runtime");
307
- function isUiNodeInputAttributes(attributes) {
719
+ // src/form/verification.tsx
720
+ var import_jsx_runtime16 = require("react/jsx-runtime");
721
+ function VerificationForm({
722
+ flow,
723
+ Header,
724
+ autoRedirect = true
725
+ }) {
726
+ const nodesByGroup = groupNodesByGroup(flow.ui.nodes);
727
+ const csrfToken = findCsrfToken(flow.ui.nodes);
728
+ const codeNodes = nodesByGroup.code || [];
729
+ const inputNodes = filterInputNodes(sortNodes(codeNodes));
730
+ const submitButton = findSubmitButton(sortNodes(codeNodes));
731
+ const anchorNode = findAnchorNode(sortNodes(codeNodes));
732
+ React8.useEffect(() => {
733
+ if (autoRedirect && anchorNode && anchorNode.type === "a" && "href" in anchorNode.attributes) {
734
+ const href = anchorNode.attributes.href;
735
+ if (href && typeof window !== "undefined") {
736
+ window.location.href = href;
737
+ }
738
+ }
739
+ }, [autoRedirect, anchorNode]);
740
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
741
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Messages, { flow }),
742
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Card, { className: "w-full max-w-md mx-auto", children: [
743
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(CardHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(CardTitle, { className: "text-center pb-1", children: Header || "Verification Code" }) }),
744
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(CardContent, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("form", { action: flow.ui.action, method: flow.ui.method, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "space-y-4", children: [
745
+ csrfToken && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(HiddenInput, { node: csrfToken }),
746
+ inputNodes.map((node, idx) => {
747
+ const isCodeInput = node.attributes.node_type === "input" && "name" in node.attributes && node.attributes.name === "code";
748
+ const initialValue = isCodeInput && "value" in node.attributes ? String(node.attributes.value || "") : "";
749
+ return isCodeInput ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
750
+ PinInput,
751
+ {
752
+ node,
753
+ length: 6,
754
+ initialValue
755
+ },
756
+ idx
757
+ ) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(FormInput, { node }, idx);
758
+ }),
759
+ submitButton && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SubmitButton, { node: submitButton }),
760
+ !submitButton && anchorNode && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AnchorButton, { node: anchorNode })
761
+ ] }) }) })
762
+ ] })
763
+ ] });
764
+ }
765
+
766
+ // src/form/recovery.tsx
767
+ var import_jsx_runtime17 = require("react/jsx-runtime");
768
+ function RecoveryForm({ flow, Header }) {
769
+ const nodesByGroup = groupNodesByGroup(flow.ui.nodes);
770
+ const csrfToken = findCsrfToken(flow.ui.nodes);
771
+ const codeNodes = nodesByGroup.code || [];
772
+ const linkNodes = nodesByGroup.link || [];
773
+ const activeNodes = codeNodes.length > 0 ? codeNodes : linkNodes;
774
+ const inputNodes = filterInputNodes(sortNodes(activeNodes));
775
+ const submitButton = findSubmitButton(sortNodes(activeNodes));
776
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
777
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Messages, { flow }),
778
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Card, { className: "w-full max-w-md mx-auto", children: [
779
+ Header && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(CardHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(CardTitle, { className: "text-center pb-1", children: Header }) }),
780
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(CardContent, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("form", { action: flow.ui.action, method: flow.ui.method, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "space-y-4", children: [
781
+ csrfToken && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(HiddenInput, { node: csrfToken }),
782
+ inputNodes.map((node, idx) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(FormInput, { node }, idx)),
783
+ submitButton && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SubmitButton, { node: submitButton })
784
+ ] }) }) })
785
+ ] })
786
+ ] });
787
+ }
788
+
789
+ // src/form/settings.tsx
790
+ var import_jsx_runtime18 = require("react/jsx-runtime");
791
+ function isUiNodeInputAttributes2(attributes) {
308
792
  return attributes && typeof attributes === "object" && "name" in attributes && "type" in attributes;
309
793
  }
310
- function CustomFlowForm({ flow, Header }) {
794
+ function SettingsForm({ flow }) {
311
795
  const nodesByGroup = flow.ui.nodes.reduce((groups, node) => {
312
796
  const group = node.group || "default";
313
797
  if (!groups[group]) {
@@ -316,150 +800,128 @@ function CustomFlowForm({ flow, Header }) {
316
800
  groups[group].push(node);
317
801
  return groups;
318
802
  }, {});
319
- const oidcNodes = nodesByGroup.oidc || [];
320
- const regularNodes = Object.entries(nodesByGroup).filter(([group]) => group !== "oidc").flatMap(([, nodes]) => nodes);
321
- const csrfToken = regularNodes.find(
322
- (node) => isUiNodeInputAttributes(node.attributes) && node.attributes.name === "csrf_token"
803
+ const csrfToken = flow.ui.nodes.find(
804
+ (node) => isUiNodeInputAttributes2(node.attributes) && node.attributes.name === "csrf_token"
323
805
  );
324
- const hasSubmitButton = flow.ui.nodes.some(
325
- (node) => isUiNodeInputAttributes(node.attributes) && node.attributes.type === "submit"
806
+ const settingsGroups = Object.entries(nodesByGroup).filter(
807
+ ([group]) => group !== "default" && group !== "oidc"
326
808
  );
327
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { children: [
328
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Messages, { flow }),
329
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Card, { className: "w-full max-w-md mx-auto", children: [
330
- Header && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CardHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CardTitle, { className: "text-center pb-1", children: Header }) }),
331
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(CardContent, { className: "space-y-6", children: [
332
- oidcNodes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "space-y-3", children: [
333
- oidcNodes.map((node, index) => {
334
- if (isUiNodeInputAttributes(node.attributes) && node.attributes.type === "submit") {
335
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
336
- "form",
809
+ const groupTitles = {
810
+ profile: "Profile",
811
+ password: "Password",
812
+ totp: "Authenticator App",
813
+ webauthn: "Security Keys",
814
+ lookup_secret: "Backup Recovery Codes",
815
+ passkey: "Passkeys"
816
+ };
817
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "space-y-6", children: [
818
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Messages, { flow }),
819
+ settingsGroups.map(([groupName, nodes]) => {
820
+ const submitButton = nodes.find(
821
+ (node) => isUiNodeInputAttributes2(node.attributes) && node.attributes.type === "submit"
822
+ );
823
+ const inputNodes = nodes.filter(
824
+ (node) => isUiNodeInputAttributes2(node.attributes) && node.attributes.type !== "submit" && node.attributes.type !== "hidden"
825
+ );
826
+ const imageNodes = nodes.filter((node) => node.type === "img");
827
+ const textNodes = nodes.filter((node) => node.type === "text");
828
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Card, { className: "w-full max-w-2xl mx-auto", children: [
829
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(CardHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(CardTitle, { children: groupTitles[groupName] || groupName }) }),
830
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(CardContent, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("form", { action: flow.ui.action, method: flow.ui.method, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "space-y-4", children: [
831
+ csrfToken && isUiNodeInputAttributes2(csrfToken.attributes) && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
832
+ "input",
833
+ {
834
+ name: csrfToken.attributes.name,
835
+ type: "hidden",
836
+ value: csrfToken.attributes.value || "",
837
+ readOnly: true
838
+ }
839
+ ),
840
+ imageNodes.map((node, index) => {
841
+ if (node.type === "img" && "src" in node.attributes) {
842
+ const imgAttrs = node.attributes;
843
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
844
+ "div",
337
845
  {
338
- action: flow.ui.action,
339
- method: flow.ui.method,
340
- className: "w-full",
341
- children: [
342
- csrfToken && isUiNodeInputAttributes(csrfToken.attributes) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
343
- "input",
344
- {
345
- name: csrfToken.attributes.name,
346
- type: "hidden",
347
- value: csrfToken.attributes.value || "",
348
- readOnly: true
349
- }
350
- ),
351
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
352
- Button,
353
- {
354
- type: "submit",
355
- name: node.attributes.name,
356
- value: node.attributes.value || "",
357
- variant: "outline",
358
- className: "w-full",
359
- children: node.meta.label?.text || node.attributes.value || "Sign in"
360
- }
361
- )
362
- ]
846
+ className: "flex justify-center",
847
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
848
+ "img",
849
+ {
850
+ src: imgAttrs.src,
851
+ alt: node.meta.label?.text || "QR Code",
852
+ width: imgAttrs.width,
853
+ height: imgAttrs.height,
854
+ className: "border rounded-lg"
855
+ }
856
+ )
363
857
  },
364
- `oidc-${index}`
858
+ `img-${index}`
365
859
  );
366
860
  }
367
861
  return null;
368
862
  }),
369
- regularNodes.some(
370
- (node) => isUiNodeInputAttributes(node.attributes) && !["hidden", "submit"].includes(node.attributes.type)
371
- ) && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "relative my-6", children: [
372
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "absolute inset-0 flex items-center", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "w-full border-t border-border" }) }),
373
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "relative flex justify-center text-xs uppercase", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "bg-background px-3 text-muted-foreground font-medium", children: "Or continue with email" }) })
374
- ] })
375
- ] }),
376
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("form", { action: flow.ui.action, method: flow.ui.method, children: [
377
- regularNodes.map((node) => {
378
- if (isUiNodeInputAttributes(node.attributes)) {
379
- const isSubmitButton = node.attributes.type === "submit";
380
- const isHiddenField = node.attributes.type === "hidden";
381
- const isVisibleField = !isHiddenField && !isSubmitButton;
382
- if (isHiddenField) {
383
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
384
- "input",
385
- {
386
- name: node.attributes.name,
387
- type: "hidden",
388
- value: node.attributes.value || "",
389
- readOnly: true
390
- },
391
- node.attributes.name
392
- );
393
- }
394
- if (isSubmitButton) {
395
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
396
- Button,
863
+ textNodes.map((node, index) => {
864
+ if (node.type === "text" && "text" in node.attributes) {
865
+ const textContent = typeof node.attributes.text === "string" ? node.attributes.text : node.attributes.text?.text || "";
866
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "space-y-2", children: [
867
+ node.meta.label?.text && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Label, { className: "text-sm text-muted-foreground", children: node.meta.label.text }),
868
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "p-3 bg-muted rounded-md font-mono text-sm break-all", children: textContent })
869
+ ] }, `text-${index}`);
870
+ }
871
+ return null;
872
+ }),
873
+ inputNodes.map((node) => {
874
+ if (isUiNodeInputAttributes2(node.attributes)) {
875
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "space-y-2", children: [
876
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Label, { htmlFor: node.attributes.name, children: [
877
+ node.meta.label?.text,
878
+ node.attributes.required && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-destructive ml-1", children: "*" })
879
+ ] }),
880
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
881
+ Input,
397
882
  {
398
- type: "submit",
883
+ id: node.attributes.name,
399
884
  name: node.attributes.name,
400
- value: node.attributes.value || "",
401
- className: "w-full mt-2",
402
- children: node.meta.label?.text || node.attributes.value || "Submit"
403
- },
404
- node.attributes.name
405
- );
406
- }
407
- if (isVisibleField && [
408
- "default",
409
- "password",
410
- "code",
411
- "webauthn",
412
- "passkey",
413
- "totp",
414
- "lookup_secret",
415
- "profile"
416
- ].includes(node.group)) {
417
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
418
- "div",
419
- {
420
- className: "space-y-2 mb-4",
421
- children: [
422
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Label, { htmlFor: node.attributes.name, children: [
423
- node.meta.label?.text,
424
- node.attributes.required && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-destructive ml-1", children: "*" })
425
- ] }),
426
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
427
- Input,
428
- {
429
- id: node.attributes.name,
430
- name: node.attributes.name,
431
- type: node.attributes.type,
432
- defaultValue: node.attributes.value || "",
433
- required: node.attributes.required,
434
- placeholder: `Enter your ${node.meta.label?.text?.toLowerCase() || node.attributes.name}`
435
- }
436
- )
437
- ]
438
- },
439
- node.meta.label?.id || node.attributes.name
440
- );
441
- }
885
+ type: node.attributes.type,
886
+ defaultValue: node.attributes.value || "",
887
+ required: node.attributes.required,
888
+ disabled: node.attributes.disabled,
889
+ autoComplete: node.attributes.autocomplete,
890
+ placeholder: `Enter ${node.meta.label?.text?.toLowerCase() || node.attributes.name}`
891
+ }
892
+ )
893
+ ] }, node.attributes.name);
442
894
  }
443
895
  return null;
444
896
  }),
445
- !hasSubmitButton && !oidcNodes.length && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Button, { type: "submit", className: "w-full", children: "Submit" })
446
- ] })
447
- ] })
448
- ] })
897
+ submitButton && isUiNodeInputAttributes2(submitButton.attributes) && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
898
+ Button,
899
+ {
900
+ type: "submit",
901
+ name: submitButton.attributes.name,
902
+ value: submitButton.attributes.value || "",
903
+ className: "w-full",
904
+ disabled: submitButton.attributes.disabled,
905
+ children: submitButton.meta.label?.text || submitButton.attributes.value || "Save"
906
+ }
907
+ )
908
+ ] }) }) })
909
+ ] }, groupName);
910
+ })
449
911
  ] });
450
912
  }
451
913
 
452
914
  // src/tenant-switcher/index.tsx
453
- var React8 = __toESM(require("react"), 1);
915
+ var React10 = __toESM(require("react"), 1);
454
916
 
455
917
  // src/components/ui/select.tsx
456
- var React7 = __toESM(require("react"), 1);
918
+ var React9 = __toESM(require("react"), 1);
457
919
  var SelectPrimitive = __toESM(require("@radix-ui/react-select"), 1);
458
920
  var import_lucide_react = require("lucide-react");
459
- var import_jsx_runtime8 = require("react/jsx-runtime");
921
+ var import_jsx_runtime19 = require("react/jsx-runtime");
460
922
  var Select = SelectPrimitive.Root;
461
923
  var SelectValue = SelectPrimitive.Value;
462
- var SelectTrigger = React7.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
924
+ var SelectTrigger = React9.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
463
925
  SelectPrimitive.Trigger,
464
926
  {
465
927
  ref,
@@ -470,12 +932,12 @@ var SelectTrigger = React7.forwardRef(({ className, children, ...props }, ref) =
470
932
  ...props,
471
933
  children: [
472
934
  children,
473
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react.ChevronDown, { className: "h-4 w-4 opacity-50" }) })
935
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react.ChevronDown, { className: "h-4 w-4 opacity-50" }) })
474
936
  ]
475
937
  }
476
938
  ));
477
939
  SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
478
- var SelectScrollUpButton = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
940
+ var SelectScrollUpButton = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
479
941
  SelectPrimitive.ScrollUpButton,
480
942
  {
481
943
  ref,
@@ -484,11 +946,11 @@ var SelectScrollUpButton = React7.forwardRef(({ className, ...props }, ref) => /
484
946
  className
485
947
  ),
486
948
  ...props,
487
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react.ChevronUp, { className: "h-4 w-4" })
949
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react.ChevronUp, { className: "h-4 w-4" })
488
950
  }
489
951
  ));
490
952
  SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
491
- var SelectScrollDownButton = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
953
+ var SelectScrollDownButton = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
492
954
  SelectPrimitive.ScrollDownButton,
493
955
  {
494
956
  ref,
@@ -497,11 +959,11 @@ var SelectScrollDownButton = React7.forwardRef(({ className, ...props }, ref) =>
497
959
  className
498
960
  ),
499
961
  ...props,
500
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react.ChevronDown, { className: "h-4 w-4" })
962
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react.ChevronDown, { className: "h-4 w-4" })
501
963
  }
502
964
  ));
503
965
  SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
504
- var SelectContent = React7.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SelectPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
966
+ var SelectContent = React9.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SelectPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
505
967
  SelectPrimitive.Content,
506
968
  {
507
969
  ref,
@@ -513,8 +975,8 @@ var SelectContent = React7.forwardRef(({ className, children, position = "popper
513
975
  position,
514
976
  ...props,
515
977
  children: [
516
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SelectScrollUpButton, {}),
517
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
978
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SelectScrollUpButton, {}),
979
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
518
980
  SelectPrimitive.Viewport,
519
981
  {
520
982
  className: cn(
@@ -524,12 +986,12 @@ var SelectContent = React7.forwardRef(({ className, children, position = "popper
524
986
  children
525
987
  }
526
988
  ),
527
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SelectScrollDownButton, {})
989
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SelectScrollDownButton, {})
528
990
  ]
529
991
  }
530
992
  ) }));
531
993
  SelectContent.displayName = SelectPrimitive.Content.displayName;
532
- var SelectLabel = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
994
+ var SelectLabel = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
533
995
  SelectPrimitive.Label,
534
996
  {
535
997
  ref,
@@ -538,7 +1000,7 @@ var SelectLabel = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE
538
1000
  }
539
1001
  ));
540
1002
  SelectLabel.displayName = SelectPrimitive.Label.displayName;
541
- var SelectItem = React7.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1003
+ var SelectItem = React9.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
542
1004
  SelectPrimitive.Item,
543
1005
  {
544
1006
  ref,
@@ -548,13 +1010,13 @@ var SelectItem = React7.forwardRef(({ className, children, ...props }, ref) => /
548
1010
  ),
549
1011
  ...props,
550
1012
  children: [
551
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react.Check, { className: "h-4 w-4" }) }) }),
552
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SelectPrimitive.ItemText, { children })
1013
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react.Check, { className: "h-4 w-4" }) }) }),
1014
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SelectPrimitive.ItemText, { children })
553
1015
  ]
554
1016
  }
555
1017
  ));
556
1018
  SelectItem.displayName = SelectPrimitive.Item.displayName;
557
- var SelectSeparator = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1019
+ var SelectSeparator = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
558
1020
  SelectPrimitive.Separator,
559
1021
  {
560
1022
  ref,
@@ -565,7 +1027,7 @@ var SelectSeparator = React7.forwardRef(({ className, ...props }, ref) => /* @__
565
1027
  SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
566
1028
 
567
1029
  // src/tenant-switcher/index.tsx
568
- var import_jsx_runtime9 = require("react/jsx-runtime");
1030
+ var import_jsx_runtime20 = require("react/jsx-runtime");
569
1031
  function SwitchActiveTenant({
570
1032
  tenants,
571
1033
  currentTenantId,
@@ -574,7 +1036,7 @@ function SwitchActiveTenant({
574
1036
  className,
575
1037
  onTenantChange
576
1038
  }) {
577
- const [isLoading, setIsLoading] = React8.useState(false);
1039
+ const [isLoading, setIsLoading] = React10.useState(false);
578
1040
  const handleTenantChange = async (tenantId) => {
579
1041
  if (tenantId === currentTenantId) return;
580
1042
  setIsLoading(true);
@@ -592,24 +1054,24 @@ function SwitchActiveTenant({
592
1054
  }
593
1055
  };
594
1056
  const currentTenant = tenants.find((tenant) => tenant.id === currentTenantId);
595
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1057
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
596
1058
  Select,
597
1059
  {
598
1060
  value: currentTenantId,
599
1061
  onValueChange: handleTenantChange,
600
1062
  disabled: isLoading,
601
1063
  children: [
602
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SelectTrigger, { className: cn("max-w-64", className), children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SelectValue, { placeholder, children: currentTenant ? currentTenant.name : placeholder }) }),
603
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SelectContent, { children: tenants.map((tenant) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SelectItem, { value: tenant.id, children: tenant.name }, tenant.id)) })
1064
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SelectTrigger, { className: cn("max-w-64", className), children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SelectValue, { placeholder, children: currentTenant ? currentTenant.name : placeholder }) }),
1065
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SelectContent, { children: tenants.map((tenant) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SelectItem, { value: tenant.id, children: tenant.name }, tenant.id)) })
604
1066
  ]
605
1067
  }
606
1068
  );
607
1069
  }
608
1070
 
609
1071
  // src/pricing-table/index.tsx
610
- var React9 = __toESM(require("react"), 1);
1072
+ var React11 = __toESM(require("react"), 1);
611
1073
  var import_lucide_react2 = require("lucide-react");
612
- var import_jsx_runtime10 = require("react/jsx-runtime");
1074
+ var import_jsx_runtime21 = require("react/jsx-runtime");
613
1075
  var getCurrencySymbol = (currency) => {
614
1076
  const symbols = {
615
1077
  USD: "$",
@@ -650,7 +1112,7 @@ function PricingCard({
650
1112
  }) {
651
1113
  const ui = product.ui || {};
652
1114
  const isHighlighted = ui.highlighted;
653
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1115
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
654
1116
  "div",
655
1117
  {
656
1118
  className: cn(
@@ -658,11 +1120,11 @@ function PricingCard({
658
1120
  isHighlighted ? "relative" : ""
659
1121
  ),
660
1122
  children: [
661
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "h-4 flex-shrink-0 relative", children: ui.badge && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "absolute top-0 left-1/2 transform -translate-x-1/2 z-10", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "bg-primary text-primary-foreground px-3 py-1 rounded-full text-sm font-medium flex items-center gap-1 whitespace-nowrap shadow-md", children: [
662
- ui.badge === "Most Popular" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react2.Star, { className: "w-3 h-3" }),
1123
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "h-4 flex-shrink-0 relative", children: ui.badge && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "absolute top-0 left-1/2 transform -translate-x-1/2 z-10", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "bg-primary text-primary-foreground px-3 py-1 rounded-full text-sm font-medium flex items-center gap-1 whitespace-nowrap shadow-md", children: [
1124
+ ui.badge === "Most Popular" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react2.Star, { className: "w-3 h-3" }),
663
1125
  ui.badge
664
1126
  ] }) }) }),
665
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1127
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
666
1128
  Card,
667
1129
  {
668
1130
  className: cn(
@@ -671,36 +1133,36 @@ function PricingCard({
671
1133
  isSelected && "ring-2 ring-primary"
672
1134
  ),
673
1135
  children: [
674
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(CardHeader, { className: "text-center", children: [
675
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(CardTitle, { className: "text-xl font-bold", children: ui.display_name || product.name }),
676
- ui.tagline && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(CardDescription, { className: "text-base", children: ui.tagline })
1136
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(CardHeader, { className: "text-center", children: [
1137
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CardTitle, { className: "text-xl font-bold", children: ui.display_name || product.name }),
1138
+ ui.tagline && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CardDescription, { className: "text-base", children: ui.tagline })
677
1139
  ] }),
678
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(CardContent, { className: "flex-1 space-y-6", children: [
679
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "text-center", children: [
680
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "text-3xl font-bold", children: formatPrice(displayedPrice) }),
681
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "text-sm text-muted-foreground", children: formatBillingPeriod(displayedPrice) })
1140
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(CardContent, { className: "flex-1 space-y-6", children: [
1141
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "text-center", children: [
1142
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "text-3xl font-bold", children: formatPrice(displayedPrice) }),
1143
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "text-sm text-muted-foreground", children: formatBillingPeriod(displayedPrice) })
682
1144
  ] }),
683
- (ui.features && ui.features.length > 0 || displayedPrice.ui?.features?.length > 0 || displayedPrice.ui?.limits?.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "space-y-4", children: [
684
- ui.features && ui.features.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "space-y-2", children: [
685
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h4", { className: "font-medium text-sm text-muted-foreground uppercase tracking-wide", children: "Features" }),
686
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("ul", { className: "space-y-2", children: ui.features.map((feature, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("li", { className: "flex items-start gap-2", children: [
687
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react2.Check, { className: "w-4 h-4 text-green-500 mt-0.5 flex-shrink-0" }),
688
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-sm", children: feature })
1145
+ (ui.features && ui.features.length > 0 || displayedPrice.ui?.features?.length > 0 || displayedPrice.ui?.limits?.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "space-y-4", children: [
1146
+ ui.features && ui.features.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "space-y-2", children: [
1147
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h4", { className: "font-medium text-sm text-muted-foreground uppercase tracking-wide", children: "Features" }),
1148
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("ul", { className: "space-y-2", children: ui.features.map((feature, index) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("li", { className: "flex items-start gap-2", children: [
1149
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react2.Check, { className: "w-4 h-4 text-green-500 mt-0.5 flex-shrink-0" }),
1150
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-sm", children: feature })
689
1151
  ] }, index)) })
690
1152
  ] }),
691
- displayedPrice.ui?.features && displayedPrice.ui.features.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "space-y-2", children: [
692
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h4", { className: "font-medium text-sm text-muted-foreground uppercase tracking-wide", children: "This Plan" }),
693
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("ul", { className: "space-y-2", children: displayedPrice.ui.features.map(
694
- (feature, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("li", { className: "flex items-start gap-2", children: [
695
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react2.Check, { className: "w-4 h-4 text-blue-500 mt-0.5 flex-shrink-0" }),
696
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-sm", children: feature })
1153
+ displayedPrice.ui?.features && displayedPrice.ui.features.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "space-y-2", children: [
1154
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h4", { className: "font-medium text-sm text-muted-foreground uppercase tracking-wide", children: "This Plan" }),
1155
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("ul", { className: "space-y-2", children: displayedPrice.ui.features.map(
1156
+ (feature, index) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("li", { className: "flex items-start gap-2", children: [
1157
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react2.Check, { className: "w-4 h-4 text-blue-500 mt-0.5 flex-shrink-0" }),
1158
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-sm", children: feature })
697
1159
  ] }, index)
698
1160
  ) })
699
1161
  ] }),
700
- displayedPrice.ui?.limits && displayedPrice.ui.limits.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "space-y-2", children: [
701
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h4", { className: "font-medium text-sm text-muted-foreground uppercase tracking-wide", children: "Usage Limits" }),
702
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("ul", { className: "space-y-1", children: displayedPrice.ui.limits.map(
703
- (limit, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1162
+ displayedPrice.ui?.limits && displayedPrice.ui.limits.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "space-y-2", children: [
1163
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h4", { className: "font-medium text-sm text-muted-foreground uppercase tracking-wide", children: "Usage Limits" }),
1164
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("ul", { className: "space-y-1", children: displayedPrice.ui.limits.map(
1165
+ (limit, index) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
704
1166
  "li",
705
1167
  {
706
1168
  className: "text-sm text-muted-foreground",
@@ -712,7 +1174,7 @@ function PricingCard({
712
1174
  ] })
713
1175
  ] })
714
1176
  ] }),
715
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(CardFooter, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1177
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CardFooter, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
716
1178
  Button,
717
1179
  {
718
1180
  className: "w-full",
@@ -739,24 +1201,24 @@ function PricingTable({
739
1201
  showPricingToggle = false,
740
1202
  defaultInterval = "month"
741
1203
  }) {
742
- const [selectedInterval, setSelectedInterval] = React9.useState(defaultInterval);
743
- const [carouselIndex, setCarouselIndex] = React9.useState(0);
744
- const sortedProducts = React9.useMemo(
1204
+ const [selectedInterval, setSelectedInterval] = React11.useState(defaultInterval);
1205
+ const [carouselIndex, setCarouselIndex] = React11.useState(0);
1206
+ const sortedProducts = React11.useMemo(
745
1207
  () => [...products].sort(
746
1208
  (a, b) => (a.ui?.sort_order ?? 999) - (b.ui?.sort_order ?? 999)
747
1209
  ),
748
1210
  [products]
749
1211
  );
750
- const hasMultipleIntervals = React9.useMemo(
1212
+ const hasMultipleIntervals = React11.useMemo(
751
1213
  () => products.some(
752
1214
  (p) => new Set(p.prices.map((price) => price.interval)).size > 1
753
1215
  ),
754
1216
  [products]
755
1217
  );
756
- const getDisplayedPrice = (product) => product.prices.find((p) => p.interval === selectedInterval) || product.prices[0];
1218
+ const getDisplayedPrice = (product) => product.prices.find((price) => price.interval === selectedInterval) || product.prices[0];
757
1219
  const renderCard = (product) => {
758
1220
  const displayedPrice = getDisplayedPrice(product);
759
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1221
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
760
1222
  PricingCard,
761
1223
  {
762
1224
  product,
@@ -766,8 +1228,8 @@ function PricingTable({
766
1228
  }
767
1229
  );
768
1230
  };
769
- const desktopCarousel = /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "relative max-w-7xl mx-auto", children: [
770
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1231
+ const desktopCarousel = /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "relative max-w-7xl mx-auto", children: [
1232
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
771
1233
  Button,
772
1234
  {
773
1235
  variant: "ghost",
@@ -775,15 +1237,15 @@ function PricingTable({
775
1237
  className: "absolute left-0 top-1/2 transform -translate-y-1/2 -translate-x-4 z-10 bg-white shadow-lg border hover:bg-gray-50 disabled:opacity-50",
776
1238
  onClick: () => setCarouselIndex(Math.max(0, carouselIndex - 1)),
777
1239
  disabled: carouselIndex === 0,
778
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react2.ChevronLeft, { className: "w-4 h-4" })
1240
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react2.ChevronLeft, { className: "w-4 h-4" })
779
1241
  }
780
1242
  ),
781
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1243
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
782
1244
  "div",
783
1245
  {
784
1246
  className: "overflow-hidden mx-auto",
785
1247
  style: { width: `${3 * CARD_WIDTH + 2 * GAP}px` },
786
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1248
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
787
1249
  "div",
788
1250
  {
789
1251
  className: "flex items-stretch transition-transform duration-300 ease-in-out",
@@ -791,7 +1253,7 @@ function PricingTable({
791
1253
  transform: `translateX(-${carouselIndex * (CARD_WIDTH + GAP)}px)`,
792
1254
  gap: `${GAP}px`
793
1255
  },
794
- children: sortedProducts.map((p) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1256
+ children: sortedProducts.map((p) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
795
1257
  "div",
796
1258
  {
797
1259
  style: { width: `${CARD_WIDTH}px` },
@@ -804,7 +1266,7 @@ function PricingTable({
804
1266
  )
805
1267
  }
806
1268
  ),
807
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1269
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
808
1270
  Button,
809
1271
  {
810
1272
  variant: "ghost",
@@ -814,12 +1276,12 @@ function PricingTable({
814
1276
  Math.min(sortedProducts.length - 3, carouselIndex + 1)
815
1277
  ),
816
1278
  disabled: carouselIndex >= sortedProducts.length - 3,
817
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react2.ChevronRight, { className: "w-4 h-4" })
1279
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react2.ChevronRight, { className: "w-4 h-4" })
818
1280
  }
819
1281
  ),
820
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex justify-center mt-6 space-x-2", children: Array.from(
1282
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex justify-center mt-6 space-x-2", children: Array.from(
821
1283
  { length: Math.max(1, sortedProducts.length - 2) },
822
- (_, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1284
+ (_, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
823
1285
  "button",
824
1286
  {
825
1287
  onClick: () => setCarouselIndex(i),
@@ -833,12 +1295,12 @@ function PricingTable({
833
1295
  )
834
1296
  ) })
835
1297
  ] });
836
- const staticLayout = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1298
+ const staticLayout = /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
837
1299
  "div",
838
1300
  {
839
1301
  className: "flex flex-row items-stretch justify-center",
840
1302
  style: { gap: `${GAP}px` },
841
- children: sortedProducts.map((p) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1303
+ children: sortedProducts.map((p) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
842
1304
  "div",
843
1305
  {
844
1306
  style: { width: `${CARD_WIDTH}px` },
@@ -849,9 +1311,9 @@ function PricingTable({
849
1311
  ))
850
1312
  }
851
1313
  );
852
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: cn("w-full", className), children: [
853
- showPricingToggle && hasMultipleIntervals && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex justify-center mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex bg-gray-100 p-1 rounded-lg", children: [
854
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1314
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: cn("w-full", className), children: [
1315
+ showPricingToggle && hasMultipleIntervals && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex justify-center mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex bg-gray-100 p-1 rounded-lg", children: [
1316
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
855
1317
  Button,
856
1318
  {
857
1319
  variant: selectedInterval === "month" ? "default" : "ghost",
@@ -861,7 +1323,7 @@ function PricingTable({
861
1323
  children: "Monthly"
862
1324
  }
863
1325
  ),
864
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1326
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
865
1327
  Button,
866
1328
  {
867
1329
  variant: selectedInterval === "year" ? "default" : "ghost",
@@ -872,20 +1334,20 @@ function PricingTable({
872
1334
  }
873
1335
  )
874
1336
  ] }) }),
875
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "lg:hidden relative", children: [
876
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1337
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "lg:hidden relative", children: [
1338
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
877
1339
  "div",
878
1340
  {
879
1341
  className: "overflow-hidden mx-auto",
880
1342
  style: { width: `${CARD_WIDTH}px` },
881
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1343
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
882
1344
  "div",
883
1345
  {
884
1346
  className: "flex transition-transform duration-300 ease-in-out items-stretch",
885
1347
  style: {
886
1348
  transform: `translateX(-${carouselIndex * CARD_WIDTH}px)`
887
1349
  },
888
- children: sortedProducts.map((product) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1350
+ children: sortedProducts.map((product) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
889
1351
  "div",
890
1352
  {
891
1353
  className: "flex-shrink-0",
@@ -898,8 +1360,8 @@ function PricingTable({
898
1360
  )
899
1361
  }
900
1362
  ),
901
- sortedProducts.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
902
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1363
+ sortedProducts.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
1364
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
903
1365
  Button,
904
1366
  {
905
1367
  variant: "ghost",
@@ -907,10 +1369,10 @@ function PricingTable({
907
1369
  className: "absolute left-0 top-1/2 -translate-y-1/2 -translate-x-2 z-10 bg-white shadow-lg border hover:bg-gray-50 disabled:opacity-50",
908
1370
  onClick: () => setCarouselIndex((prev) => Math.max(0, prev - 1)),
909
1371
  disabled: carouselIndex === 0,
910
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react2.ChevronLeft, { className: "w-5 h-5" })
1372
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react2.ChevronLeft, { className: "w-5 h-5" })
911
1373
  }
912
1374
  ),
913
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1375
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
914
1376
  Button,
915
1377
  {
916
1378
  variant: "ghost",
@@ -920,10 +1382,10 @@ function PricingTable({
920
1382
  (prev) => Math.min(sortedProducts.length - 1, prev + 1)
921
1383
  ),
922
1384
  disabled: carouselIndex >= sortedProducts.length - 1,
923
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react2.ChevronRight, { className: "w-5 h-5" })
1385
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react2.ChevronRight, { className: "w-5 h-5" })
924
1386
  }
925
1387
  ),
926
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex justify-center mt-6 space-x-2", children: Array.from({ length: sortedProducts.length }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1388
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex justify-center mt-6 space-x-2", children: Array.from({ length: sortedProducts.length }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
927
1389
  "button",
928
1390
  {
929
1391
  onClick: () => setCarouselIndex(i),
@@ -937,20 +1399,20 @@ function PricingTable({
937
1399
  )) })
938
1400
  ] })
939
1401
  ] }),
940
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hidden lg:block", children: sortedProducts.length <= 3 ? staticLayout : desktopCarousel })
1402
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "hidden lg:block", children: sortedProducts.length <= 3 ? staticLayout : desktopCarousel })
941
1403
  ] });
942
1404
  }
943
1405
 
944
1406
  // src/tenant-creator/index.tsx
945
1407
  var import_react = require("react");
946
- var import_jsx_runtime11 = require("react/jsx-runtime");
1408
+ var import_jsx_runtime22 = require("react/jsx-runtime");
947
1409
  function TenantCreator({
948
1410
  config = {},
949
1411
  formActions = {},
950
1412
  className
951
1413
  }) {
952
1414
  const [mode, setMode] = (0, import_react.useState)(
953
- config.defaultMode || "create"
1415
+ !!config.joinForm?.token?.defaultValue === true ? "join" : config.defaultMode || "create"
954
1416
  );
955
1417
  const [isLoading, setIsLoading] = (0, import_react.useState)(false);
956
1418
  const [organizationName, setOrganizationName] = (0, import_react.useState)(
@@ -959,7 +1421,9 @@ function TenantCreator({
959
1421
  const [billingEmail, setBillingEmail] = (0, import_react.useState)(
960
1422
  config.createForm?.billingEmail?.defaultValue || ""
961
1423
  );
962
- const [token, setToken] = (0, import_react.useState)("");
1424
+ const [token, setToken] = (0, import_react.useState)(
1425
+ config.joinForm?.token?.defaultValue || ""
1426
+ );
963
1427
  (0, import_react.useEffect)(() => {
964
1428
  const urlParams = new URLSearchParams(window.location.search);
965
1429
  const inviteToken = urlParams.get("invite_token");
@@ -990,14 +1454,14 @@ function TenantCreator({
990
1454
  setIsLoading(false);
991
1455
  }
992
1456
  };
993
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Card, { className: cn("w-full max-w-md mx-auto", className), children: [
994
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(CardHeader, { children: [
995
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CardTitle, { children: "Organization Setup" }),
996
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CardDescription, { children: "Choose how you want to get started with your organization." })
1457
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Card, { className: cn("w-full max-w-md mx-auto", className), children: [
1458
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(CardHeader, { children: [
1459
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CardTitle, { children: "Organization Setup" }),
1460
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CardDescription, { children: "Choose how you want to get started with your organization." })
997
1461
  ] }),
998
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(CardContent, { className: "space-y-6", children: [
999
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "grid grid-cols-2 rounded-lg bg-muted p-1", children: [
1000
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1462
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(CardContent, { className: "space-y-6", children: [
1463
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "grid grid-cols-2 rounded-lg bg-muted p-1", children: [
1464
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
1001
1465
  "label",
1002
1466
  {
1003
1467
  className: cn(
@@ -1006,7 +1470,7 @@ function TenantCreator({
1006
1470
  isLoading && "pointer-events-none opacity-50"
1007
1471
  ),
1008
1472
  children: [
1009
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1473
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1010
1474
  "input",
1011
1475
  {
1012
1476
  type: "radio",
@@ -1022,7 +1486,7 @@ function TenantCreator({
1022
1486
  ]
1023
1487
  }
1024
1488
  ),
1025
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1489
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
1026
1490
  "label",
1027
1491
  {
1028
1492
  className: cn(
@@ -1031,7 +1495,7 @@ function TenantCreator({
1031
1495
  isLoading && "pointer-events-none opacity-50"
1032
1496
  ),
1033
1497
  children: [
1034
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1498
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1035
1499
  "input",
1036
1500
  {
1037
1501
  type: "radio",
@@ -1048,10 +1512,10 @@ function TenantCreator({
1048
1512
  }
1049
1513
  )
1050
1514
  ] }),
1051
- mode === "create" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("form", { onSubmit: handleCreateSubmit, className: "space-y-4", children: [
1052
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "space-y-2", children: [
1053
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Label, { htmlFor: "organizationName", children: config.createForm?.organizationName?.label || "Organization Name" }),
1054
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1515
+ mode === "create" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("form", { onSubmit: handleCreateSubmit, className: "space-y-4", children: [
1516
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-2", children: [
1517
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Label, { htmlFor: "organizationName", children: config.createForm?.organizationName?.label || "Organization Name" }),
1518
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1055
1519
  Input,
1056
1520
  {
1057
1521
  id: "organizationName",
@@ -1065,9 +1529,9 @@ function TenantCreator({
1065
1529
  }
1066
1530
  )
1067
1531
  ] }),
1068
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "space-y-2", children: [
1069
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Label, { htmlFor: "billingEmail", children: config.createForm?.billingEmail?.label || "Billing Email" }),
1070
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1532
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-2", children: [
1533
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Label, { htmlFor: "billingEmail", children: config.createForm?.billingEmail?.label || "Billing Email" }),
1534
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1071
1535
  Input,
1072
1536
  {
1073
1537
  id: "billingEmail",
@@ -1081,12 +1545,12 @@ function TenantCreator({
1081
1545
  }
1082
1546
  )
1083
1547
  ] }),
1084
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { type: "submit", className: "w-full", disabled: isLoading, children: isLoading ? "Creating..." : "Create Organization" })
1548
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Button, { type: "submit", className: "w-full", disabled: isLoading, children: isLoading ? "Creating..." : "Create Organization" })
1085
1549
  ] }),
1086
- mode === "join" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("form", { onSubmit: handleJoinSubmit, className: "space-y-4", children: [
1087
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "space-y-2", children: [
1088
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Label, { htmlFor: "token", children: config.joinForm?.token?.label || "Invitation Token" }),
1089
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1550
+ mode === "join" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("form", { onSubmit: handleJoinSubmit, className: "space-y-4", children: [
1551
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-2", children: [
1552
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Label, { htmlFor: "token", children: config.joinForm?.token?.label || "Invitation Token" }),
1553
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1090
1554
  Input,
1091
1555
  {
1092
1556
  id: "token",
@@ -1100,15 +1564,477 @@ function TenantCreator({
1100
1564
  }
1101
1565
  )
1102
1566
  ] }),
1103
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { type: "submit", className: "w-full", disabled: isLoading, children: isLoading ? "Joining..." : "Join Organization" })
1567
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Button, { type: "submit", className: "w-full", disabled: isLoading, children: isLoading ? "Joining..." : "Join Organization" })
1568
+ ] })
1569
+ ] })
1570
+ ] });
1571
+ }
1572
+
1573
+ // src/user-invite/index.tsx
1574
+ var import_react2 = require("react");
1575
+ var import_jsx_runtime23 = require("react/jsx-runtime");
1576
+ function UserInvite({ roles, onInvite }) {
1577
+ const [email, setEmail] = (0, import_react2.useState)("");
1578
+ const [selectedRole, setSelectedRole] = (0, import_react2.useState)("");
1579
+ const [isSubmitting, setIsSubmitting] = (0, import_react2.useState)(false);
1580
+ const [error, setError] = (0, import_react2.useState)(null);
1581
+ const isValidEmail = (email2) => {
1582
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
1583
+ return emailRegex.test(email2);
1584
+ };
1585
+ const isFormValid = () => {
1586
+ return email.trim() !== "" && isValidEmail(email) && selectedRole !== "";
1587
+ };
1588
+ const handleSubmit = async (e) => {
1589
+ e.preventDefault();
1590
+ setError(null);
1591
+ if (!isFormValid()) {
1592
+ setError("Please fill in all fields with valid data");
1593
+ return;
1594
+ }
1595
+ setIsSubmitting(true);
1596
+ try {
1597
+ const inviteData = {
1598
+ email: email.trim(),
1599
+ role: selectedRole
1600
+ };
1601
+ await onInvite?.(inviteData);
1602
+ setEmail("");
1603
+ setSelectedRole("");
1604
+ } catch (err) {
1605
+ setError(
1606
+ err instanceof Error ? err.message : "Failed to send invitation"
1607
+ );
1608
+ } finally {
1609
+ setIsSubmitting(false);
1610
+ }
1611
+ };
1612
+ const handleReset = () => {
1613
+ setEmail("");
1614
+ setSelectedRole("");
1615
+ setError(null);
1616
+ };
1617
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Card, { className: "w-full max-w-2xl", children: [
1618
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(CardHeader, { children: [
1619
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CardTitle, { children: "Invite User" }),
1620
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CardDescription, { children: "Send an invitation to a new user to join your organization" })
1621
+ ] }),
1622
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CardContent, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("form", { onSubmit: handleSubmit, className: "space-y-6", children: [
1623
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "space-y-2", children: [
1624
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Label, { htmlFor: "email", children: "Email Address" }),
1625
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1626
+ Input,
1627
+ {
1628
+ id: "email",
1629
+ type: "email",
1630
+ placeholder: "colleague@company.com",
1631
+ value: email,
1632
+ onChange: (e) => setEmail(e.target.value),
1633
+ "aria-invalid": email !== "" && !isValidEmail(email)
1634
+ }
1635
+ ),
1636
+ email !== "" && !isValidEmail(email) && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-xs text-destructive", children: "Please enter a valid email address" })
1637
+ ] }),
1638
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "space-y-2", children: [
1639
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Label, { htmlFor: "role", children: "Role" }),
1640
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Select, { value: selectedRole, onValueChange: setSelectedRole, children: [
1641
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SelectTrigger, { id: "role", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SelectValue, { placeholder: "Select a role" }) }),
1642
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SelectContent, { children: roles.length > 0 ? roles.map((role) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SelectItem, { value: role, children: role }, role)) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SelectItem, { value: "no-roles", disabled: true, children: "No roles available" }) })
1643
+ ] }),
1644
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-xs text-muted-foreground", children: "The role determines what permissions the user will have" })
1645
+ ] }),
1646
+ error && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "p-3 rounded-md bg-destructive/10 border border-destructive/20", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-sm text-destructive", children: error }) }),
1647
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex justify-end space-x-3", children: [
1648
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1649
+ Button,
1650
+ {
1651
+ type: "button",
1652
+ variant: "outline",
1653
+ onClick: handleReset,
1654
+ disabled: isSubmitting,
1655
+ children: "Reset"
1656
+ }
1657
+ ),
1658
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Button, { type: "submit", disabled: !isFormValid() || isSubmitting, children: isSubmitting ? "Sending..." : "Send Invitation" })
1659
+ ] })
1660
+ ] }) })
1661
+ ] });
1662
+ }
1663
+
1664
+ // src/role-creator/index.tsx
1665
+ var import_react3 = require("react");
1666
+
1667
+ // src/components/ui/checkbox.tsx
1668
+ var React14 = require("react");
1669
+ var CheckboxPrimitive = __toESM(require("@radix-ui/react-checkbox"), 1);
1670
+ var import_lucide_react3 = require("lucide-react");
1671
+ var import_jsx_runtime24 = require("react/jsx-runtime");
1672
+ function Checkbox({
1673
+ className,
1674
+ ...props
1675
+ }) {
1676
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
1677
+ CheckboxPrimitive.Root,
1678
+ {
1679
+ "data-slot": "checkbox",
1680
+ className: cn(
1681
+ "peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
1682
+ className
1683
+ ),
1684
+ ...props,
1685
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
1686
+ CheckboxPrimitive.Indicator,
1687
+ {
1688
+ "data-slot": "checkbox-indicator",
1689
+ className: "grid place-content-center text-current transition-none",
1690
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react3.CheckIcon, { className: "size-3.5" })
1691
+ }
1692
+ )
1693
+ }
1694
+ );
1695
+ }
1696
+
1697
+ // src/components/ui/separator.tsx
1698
+ var React15 = require("react");
1699
+ var SeparatorPrimitive = __toESM(require("@radix-ui/react-separator"), 1);
1700
+ var import_jsx_runtime25 = require("react/jsx-runtime");
1701
+ function Separator2({
1702
+ className,
1703
+ orientation = "horizontal",
1704
+ decorative = true,
1705
+ ...props
1706
+ }) {
1707
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1708
+ SeparatorPrimitive.Root,
1709
+ {
1710
+ "data-slot": "separator",
1711
+ decorative,
1712
+ orientation,
1713
+ className: cn(
1714
+ "bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
1715
+ className
1716
+ ),
1717
+ ...props
1718
+ }
1719
+ );
1720
+ }
1721
+
1722
+ // src/role-creator/index.tsx
1723
+ var import_jsx_runtime26 = require("react/jsx-runtime");
1724
+ function RoleCreator({
1725
+ definitions,
1726
+ roles,
1727
+ namespaceMap = {},
1728
+ onRoleCreate,
1729
+ onRoleUpdate
1730
+ }) {
1731
+ const [roleName, setRoleName] = (0, import_react3.useState)("");
1732
+ const [selectedPermissions, setSelectedPermissions] = (0, import_react3.useState)(
1733
+ /* @__PURE__ */ new Set()
1734
+ );
1735
+ const [showSuggestions, setShowSuggestions] = (0, import_react3.useState)(false);
1736
+ const [isEditMode, setIsEditMode] = (0, import_react3.useState)(false);
1737
+ const [editingRoleId, setEditingRoleId] = (0, import_react3.useState)(null);
1738
+ const { tenantNamespace, fineGrainedNamespaces } = (0, import_react3.useMemo)(() => {
1739
+ const tenant = definitions.find(
1740
+ (def) => def.namespace.toLowerCase() === "tenant"
1741
+ );
1742
+ const fineGrained = definitions.filter(
1743
+ (def) => def.namespace.toLowerCase() !== "tenant"
1744
+ );
1745
+ return {
1746
+ tenantNamespace: tenant,
1747
+ fineGrainedNamespaces: fineGrained
1748
+ };
1749
+ }, [definitions]);
1750
+ const roleSuggestions = (0, import_react3.useMemo)(() => {
1751
+ return roles.map((role) => role.role_name);
1752
+ }, [roles]);
1753
+ const handleRoleNameChange = (value) => {
1754
+ setRoleName(value);
1755
+ const existingRole = roles.find(
1756
+ (role) => role.role_name.toLowerCase() === value.toLowerCase()
1757
+ );
1758
+ if (existingRole) {
1759
+ setIsEditMode(true);
1760
+ setEditingRoleId(existingRole.id);
1761
+ const permissions = /* @__PURE__ */ new Set();
1762
+ existingRole.permissions.forEach((perm) => {
1763
+ permissions.add(perm);
1764
+ });
1765
+ setSelectedPermissions(permissions);
1766
+ } else {
1767
+ setIsEditMode(false);
1768
+ setEditingRoleId(null);
1769
+ }
1770
+ };
1771
+ const buildPermissionString = (namespace, relation, resourceId) => {
1772
+ if (resourceId) {
1773
+ return `${namespace.toLowerCase()}:${resourceId}#${relation}`;
1774
+ }
1775
+ return `${namespace.toLowerCase()}#${relation}`;
1776
+ };
1777
+ const togglePermission = (permissionString) => {
1778
+ const newPermissions = new Set(selectedPermissions);
1779
+ if (newPermissions.has(permissionString)) {
1780
+ newPermissions.delete(permissionString);
1781
+ } else {
1782
+ newPermissions.add(permissionString);
1783
+ }
1784
+ setSelectedPermissions(newPermissions);
1785
+ };
1786
+ const handleSubmit = () => {
1787
+ if (!roleName.trim()) return;
1788
+ const permissionsArray = Array.from(selectedPermissions);
1789
+ if (isEditMode && editingRoleId) {
1790
+ onRoleUpdate?.({
1791
+ role_id: editingRoleId,
1792
+ role_name: roleName,
1793
+ permissions: permissionsArray
1794
+ });
1795
+ } else {
1796
+ onRoleCreate?.({
1797
+ role_name: roleName,
1798
+ permissions: permissionsArray
1799
+ });
1800
+ }
1801
+ };
1802
+ const handleReset = () => {
1803
+ setRoleName("");
1804
+ setSelectedPermissions(/* @__PURE__ */ new Set());
1805
+ setIsEditMode(false);
1806
+ setEditingRoleId(null);
1807
+ };
1808
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Card, { className: "w-full max-w-4xl", children: [
1809
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(CardHeader, { children: [
1810
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(CardTitle, { children: isEditMode ? `Edit Role: ${roleName}` : "Create New Role" }),
1811
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(CardDescription, { children: isEditMode ? "Update permissions for this existing role" : "Define a new role with specific permissions" })
1812
+ ] }),
1813
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(CardContent, { className: "space-y-6", children: [
1814
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "space-y-2 relative", children: [
1815
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Label, { htmlFor: "role-name", children: "Role Name" }),
1816
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1817
+ Input,
1818
+ {
1819
+ id: "role-name",
1820
+ placeholder: "Enter role name (e.g., admin, developer, viewer)",
1821
+ value: roleName,
1822
+ onChange: (e) => handleRoleNameChange(e.target.value),
1823
+ onFocus: () => setShowSuggestions(true),
1824
+ onBlur: () => setTimeout(() => setShowSuggestions(false), 200)
1825
+ }
1826
+ ),
1827
+ showSuggestions && roleSuggestions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "absolute z-10 w-full mt-1 bg-background border rounded-md shadow-lg max-h-48 overflow-y-auto", children: roleSuggestions.filter(
1828
+ (suggestion) => suggestion.toLowerCase().includes(roleName.toLowerCase())
1829
+ ).map((suggestion) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1830
+ "button",
1831
+ {
1832
+ className: "w-full px-4 py-2 text-left hover:bg-accent hover:text-accent-foreground text-sm",
1833
+ onMouseDown: () => {
1834
+ handleRoleNameChange(suggestion);
1835
+ setShowSuggestions(false);
1836
+ },
1837
+ children: suggestion
1838
+ },
1839
+ suggestion
1840
+ )) }),
1841
+ isEditMode && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "text-xs text-amber-600 dark:text-amber-400", children: "\u26A0 Editing existing role - changes will update all users with this role" })
1842
+ ] }),
1843
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Separator2, {}),
1844
+ tenantNamespace && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "space-y-4", children: [
1845
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { children: [
1846
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h3", { className: "text-lg font-semibold", children: "Organization Permissions" }),
1847
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "text-sm text-muted-foreground", children: "Tenant-wide permissions that apply across the entire organization" })
1848
+ ] }),
1849
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4 pl-4", children: tenantNamespace.relations.map((relation) => {
1850
+ const permissionString = buildPermissionString(
1851
+ tenantNamespace.namespace,
1852
+ relation
1853
+ );
1854
+ const isChecked = selectedPermissions.has(permissionString);
1855
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
1856
+ "div",
1857
+ {
1858
+ className: "flex items-center space-x-2",
1859
+ children: [
1860
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1861
+ Checkbox,
1862
+ {
1863
+ id: permissionString,
1864
+ checked: isChecked,
1865
+ onCheckedChange: () => togglePermission(permissionString)
1866
+ }
1867
+ ),
1868
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1869
+ Label,
1870
+ {
1871
+ htmlFor: permissionString,
1872
+ className: "text-sm font-normal cursor-pointer",
1873
+ children: relation.replace(/_/g, " ")
1874
+ }
1875
+ )
1876
+ ]
1877
+ },
1878
+ permissionString
1879
+ );
1880
+ }) })
1881
+ ] }),
1882
+ fineGrainedNamespaces.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
1883
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Separator2, {}),
1884
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "space-y-6", children: [
1885
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { children: [
1886
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h3", { className: "text-lg font-semibold", children: "Fine-Grained Permissions" }),
1887
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "text-sm text-muted-foreground", children: "Resource-specific permissions that require an object ID" })
1888
+ ] }),
1889
+ fineGrainedNamespaces.map((namespace) => {
1890
+ const namespaceLower = namespace.namespace.toLowerCase();
1891
+ const resourceMap = namespaceMap[namespaceLower] || [];
1892
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "space-y-4", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "pl-4", children: [
1893
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h4", { className: "text-md font-medium capitalize", children: namespace.namespace }),
1894
+ resourceMap.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "mt-4 space-y-6", children: resourceMap.map((resource) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
1895
+ "div",
1896
+ {
1897
+ className: "border rounded-lg p-4 space-y-3 bg-muted/30",
1898
+ children: [
1899
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center justify-between", children: [
1900
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "font-medium text-sm", children: resource.label }),
1901
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-xs text-muted-foreground font-mono", children: resource.id })
1902
+ ] }),
1903
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-3", children: namespace.relations.map((relation) => {
1904
+ const permissionString = buildPermissionString(
1905
+ namespace.namespace,
1906
+ relation,
1907
+ resource.id
1908
+ );
1909
+ const isChecked = selectedPermissions.has(permissionString);
1910
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
1911
+ "div",
1912
+ {
1913
+ className: "flex items-center space-x-2",
1914
+ children: [
1915
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1916
+ Checkbox,
1917
+ {
1918
+ id: permissionString,
1919
+ checked: isChecked,
1920
+ onCheckedChange: () => togglePermission(permissionString)
1921
+ }
1922
+ ),
1923
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1924
+ Label,
1925
+ {
1926
+ htmlFor: permissionString,
1927
+ className: "text-sm font-normal cursor-pointer",
1928
+ children: relation.replace(/_/g, " ")
1929
+ }
1930
+ )
1931
+ ]
1932
+ },
1933
+ permissionString
1934
+ );
1935
+ }) })
1936
+ ]
1937
+ },
1938
+ resource.id
1939
+ )) }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "mt-3 p-4 border-2 border-dashed rounded-lg text-center", children: [
1940
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("p", { className: "text-sm text-muted-foreground", children: [
1941
+ "No ",
1942
+ namespace.namespace.toLowerCase(),
1943
+ " resources available"
1944
+ ] }),
1945
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("p", { className: "text-xs text-muted-foreground mt-1", children: [
1946
+ "Use wildcard permissions (e.g., ",
1947
+ namespaceLower,
1948
+ ":*#permission) for all resources"
1949
+ ] })
1950
+ ] }),
1951
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "mt-4 space-y-2", children: [
1952
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Label, { className: "text-sm font-medium", children: [
1953
+ "Wildcard Permissions (All ",
1954
+ namespace.namespace,
1955
+ "s)"
1956
+ ] }),
1957
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-3", children: namespace.relations.map((relation) => {
1958
+ const permissionString = buildPermissionString(
1959
+ namespace.namespace,
1960
+ relation,
1961
+ "*"
1962
+ );
1963
+ const isChecked = selectedPermissions.has(permissionString);
1964
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
1965
+ "div",
1966
+ {
1967
+ className: "flex items-center space-x-2",
1968
+ children: [
1969
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1970
+ Checkbox,
1971
+ {
1972
+ id: permissionString,
1973
+ checked: isChecked,
1974
+ onCheckedChange: () => togglePermission(permissionString)
1975
+ }
1976
+ ),
1977
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
1978
+ Label,
1979
+ {
1980
+ htmlFor: permissionString,
1981
+ className: "text-sm font-normal cursor-pointer",
1982
+ children: [
1983
+ relation.replace(/_/g, " "),
1984
+ " (all)"
1985
+ ]
1986
+ }
1987
+ )
1988
+ ]
1989
+ },
1990
+ permissionString
1991
+ );
1992
+ }) })
1993
+ ] })
1994
+ ] }) }, namespace.id);
1995
+ })
1996
+ ] })
1997
+ ] }),
1998
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Separator2, {}),
1999
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "space-y-2", children: [
2000
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Label, { className: "text-sm font-medium", children: [
2001
+ "Selected Permissions (",
2002
+ selectedPermissions.size,
2003
+ ")"
2004
+ ] }),
2005
+ selectedPermissions.size > 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "p-4 bg-muted rounded-md max-h-40 overflow-y-auto", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("ul", { className: "space-y-1 text-xs font-mono", children: Array.from(selectedPermissions).map((perm) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("li", { className: "text-muted-foreground", children: perm }, perm)) }) }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "text-sm text-muted-foreground italic", children: "No permissions selected" })
2006
+ ] }),
2007
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex justify-end space-x-3", children: [
2008
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Button, { variant: "outline", onClick: handleReset, children: "Reset" }),
2009
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2010
+ Button,
2011
+ {
2012
+ onClick: handleSubmit,
2013
+ disabled: !roleName.trim() || selectedPermissions.size === 0,
2014
+ children: isEditMode ? "Update Role" : "Create Role"
2015
+ }
2016
+ )
1104
2017
  ] })
1105
2018
  ] })
1106
2019
  ] });
1107
2020
  }
1108
2021
  // Annotate the CommonJS export names for ESM import in node:
1109
2022
  0 && (module.exports = {
1110
- CustomFlowForm,
2023
+ LoginForm,
1111
2024
  PricingTable,
2025
+ RecoveryForm,
2026
+ RegistrationForm,
2027
+ RoleCreator,
2028
+ SettingsForm,
1112
2029
  SwitchActiveTenant,
1113
- TenantCreator
2030
+ TenantCreator,
2031
+ UserInvite,
2032
+ VerificationForm,
2033
+ filterInputNodes,
2034
+ findAnchorNode,
2035
+ findCsrfToken,
2036
+ findSubmitButton,
2037
+ groupNodesByGroup,
2038
+ isUiNodeInputAttributes,
2039
+ sortNodes
1114
2040
  });