@stigmer/react 0.0.89 → 0.0.91

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/identity-provider/CreateIdentityProviderForm.d.ts.map +1 -1
  2. package/identity-provider/CreateIdentityProviderForm.js +60 -2
  3. package/identity-provider/CreateIdentityProviderForm.js.map +1 -1
  4. package/identity-provider/IdentityProviderDetailPanel.d.ts.map +1 -1
  5. package/identity-provider/IdentityProviderDetailPanel.js +87 -4
  6. package/identity-provider/IdentityProviderDetailPanel.js.map +1 -1
  7. package/identity-provider/IdentityProviderListPanel.js +5 -3
  8. package/identity-provider/IdentityProviderListPanel.js.map +1 -1
  9. package/identity-provider/IdentityProviderWizard.d.ts.map +1 -1
  10. package/identity-provider/IdentityProviderWizard.js +59 -4
  11. package/identity-provider/IdentityProviderWizard.js.map +1 -1
  12. package/index.d.ts +2 -0
  13. package/index.d.ts.map +1 -1
  14. package/index.js +2 -0
  15. package/index.js.map +1 -1
  16. package/package.json +7 -7
  17. package/platform-client/CreatePlatformClientForm.d.ts +42 -0
  18. package/platform-client/CreatePlatformClientForm.d.ts.map +1 -0
  19. package/platform-client/CreatePlatformClientForm.js +148 -0
  20. package/platform-client/CreatePlatformClientForm.js.map +1 -0
  21. package/platform-client/PlatformClientDetailPanel.d.ts +51 -0
  22. package/platform-client/PlatformClientDetailPanel.d.ts.map +1 -0
  23. package/platform-client/PlatformClientDetailPanel.js +247 -0
  24. package/platform-client/PlatformClientDetailPanel.js.map +1 -0
  25. package/platform-client/PlatformClientListPanel.d.ts +41 -0
  26. package/platform-client/PlatformClientListPanel.d.ts.map +1 -0
  27. package/platform-client/PlatformClientListPanel.js +123 -0
  28. package/platform-client/PlatformClientListPanel.js.map +1 -0
  29. package/platform-client/PlatformClientSecretAlert.d.ts +39 -0
  30. package/platform-client/PlatformClientSecretAlert.d.ts.map +1 -0
  31. package/platform-client/PlatformClientSecretAlert.js +74 -0
  32. package/platform-client/PlatformClientSecretAlert.js.map +1 -0
  33. package/platform-client/index.d.ts +11 -0
  34. package/platform-client/index.d.ts.map +1 -0
  35. package/platform-client/index.js +11 -0
  36. package/platform-client/index.js.map +1 -0
  37. package/platform-client/useCreatePlatformClient.d.ts +42 -0
  38. package/platform-client/useCreatePlatformClient.d.ts.map +1 -0
  39. package/platform-client/useCreatePlatformClient.js +49 -0
  40. package/platform-client/useCreatePlatformClient.js.map +1 -0
  41. package/platform-client/useDeletePlatformClient.d.ts +31 -0
  42. package/platform-client/useDeletePlatformClient.d.ts.map +1 -0
  43. package/platform-client/useDeletePlatformClient.js +42 -0
  44. package/platform-client/useDeletePlatformClient.js.map +1 -0
  45. package/platform-client/usePlatformClient.d.ts +37 -0
  46. package/platform-client/usePlatformClient.d.ts.map +1 -0
  47. package/platform-client/usePlatformClient.js +62 -0
  48. package/platform-client/usePlatformClient.js.map +1 -0
  49. package/platform-client/usePlatformClientList.d.ts +42 -0
  50. package/platform-client/usePlatformClientList.d.ts.map +1 -0
  51. package/platform-client/usePlatformClientList.js +71 -0
  52. package/platform-client/usePlatformClientList.js.map +1 -0
  53. package/platform-client/useRotatePlatformClientSecret.d.ts +35 -0
  54. package/platform-client/useRotatePlatformClientSecret.d.ts.map +1 -0
  55. package/platform-client/useRotatePlatformClientSecret.js +43 -0
  56. package/platform-client/useRotatePlatformClientSecret.js.map +1 -0
  57. package/platform-client/useUpdatePlatformClient.d.ts +39 -0
  58. package/platform-client/useUpdatePlatformClient.d.ts.map +1 -0
  59. package/platform-client/useUpdatePlatformClient.js +50 -0
  60. package/platform-client/useUpdatePlatformClient.js.map +1 -0
  61. package/src/identity-provider/CreateIdentityProviderForm.tsx +220 -0
  62. package/src/identity-provider/IdentityProviderDetailPanel.tsx +288 -6
  63. package/src/identity-provider/IdentityProviderListPanel.tsx +9 -2
  64. package/src/identity-provider/IdentityProviderWizard.tsx +231 -25
  65. package/src/index.ts +26 -0
  66. package/src/platform-client/CreatePlatformClientForm.tsx +519 -0
  67. package/src/platform-client/PlatformClientDetailPanel.tsx +898 -0
  68. package/src/platform-client/PlatformClientListPanel.tsx +413 -0
  69. package/src/platform-client/PlatformClientSecretAlert.tsx +252 -0
  70. package/src/platform-client/index.ts +49 -0
  71. package/src/platform-client/useCreatePlatformClient.ts +77 -0
  72. package/src/platform-client/useDeletePlatformClient.ts +64 -0
  73. package/src/platform-client/usePlatformClient.ts +86 -0
  74. package/src/platform-client/usePlatformClientList.ts +96 -0
  75. package/src/platform-client/useRotatePlatformClientSecret.ts +68 -0
  76. package/src/platform-client/useUpdatePlatformClient.ts +70 -0
  77. package/src/test/index.ts +6 -0
  78. package/src/{demo → test}/samples.ts +1 -1
  79. package/styles.css +1 -1
  80. package/test/__tests__/samples.test.d.ts.map +1 -0
  81. package/{demo → test}/__tests__/samples.test.js.map +1 -1
  82. package/test/index.d.ts +2 -0
  83. package/test/index.d.ts.map +1 -0
  84. package/test/index.js +6 -0
  85. package/test/index.js.map +1 -0
  86. package/{demo → test}/samples.d.ts +1 -1
  87. package/{demo → test}/samples.d.ts.map +1 -1
  88. package/{demo → test}/samples.js +1 -1
  89. package/{demo → test}/samples.js.map +1 -1
  90. package/demo/__tests__/demo-client.test.d.ts +0 -2
  91. package/demo/__tests__/demo-client.test.d.ts.map +0 -1
  92. package/demo/__tests__/demo-client.test.js +0 -133
  93. package/demo/__tests__/demo-client.test.js.map +0 -1
  94. package/demo/__tests__/fixtures.test.d.ts +0 -2
  95. package/demo/__tests__/fixtures.test.d.ts.map +0 -1
  96. package/demo/__tests__/fixtures.test.js +0 -135
  97. package/demo/__tests__/fixtures.test.js.map +0 -1
  98. package/demo/__tests__/samples.test.d.ts.map +0 -1
  99. package/demo/client.d.ts +0 -29
  100. package/demo/client.d.ts.map +0 -1
  101. package/demo/client.js +0 -52
  102. package/demo/client.js.map +0 -1
  103. package/demo/fixtures.d.ts +0 -194
  104. package/demo/fixtures.d.ts.map +0 -1
  105. package/demo/fixtures.js +0 -267
  106. package/demo/fixtures.js.map +0 -1
  107. package/demo/index.d.ts +0 -6
  108. package/demo/index.d.ts.map +0 -1
  109. package/demo/index.js +0 -6
  110. package/demo/index.js.map +0 -1
  111. package/demo/transport.d.ts +0 -59
  112. package/demo/transport.d.ts.map +0 -1
  113. package/demo/transport.js +0 -75
  114. package/demo/transport.js.map +0 -1
  115. package/demo/types.d.ts +0 -62
  116. package/demo/types.d.ts.map +0 -1
  117. package/demo/types.js +0 -16
  118. package/demo/types.js.map +0 -1
  119. package/src/demo/__tests__/demo-client.test.tsx +0 -213
  120. package/src/demo/__tests__/fixtures.test.ts +0 -214
  121. package/src/demo/client.ts +0 -78
  122. package/src/demo/fixtures.ts +0 -409
  123. package/src/demo/index.ts +0 -12
  124. package/src/demo/transport.ts +0 -116
  125. package/src/demo/types.ts +0 -69
  126. /package/src/{demo → test}/__tests__/samples.test.ts +0 -0
  127. /package/{demo → test}/__tests__/samples.test.d.ts +0 -0
  128. /package/{demo → test}/__tests__/samples.test.js +0 -0
@@ -0,0 +1,247 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useCallback, useState, } from "react";
4
+ import { cn } from "@stigmer/theme";
5
+ import { getUserMessage } from "@stigmer/sdk";
6
+ import { IamRole } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
7
+ import { timestampDate } from "@bufbuild/protobuf/wkt";
8
+ import { useUpdatePlatformClient } from "./useUpdatePlatformClient";
9
+ import { useRotatePlatformClientSecret } from "./useRotatePlatformClientSecret";
10
+ import { useDeletePlatformClient } from "./useDeletePlatformClient";
11
+ /**
12
+ * View and edit panel for an existing platform client.
13
+ *
14
+ * In **view mode**, displays all configuration fields in a structured
15
+ * label/value layout with "Edit", "Rotate Secret", and "Delete"
16
+ * actions.
17
+ *
18
+ * In **edit mode**, mutable spec fields become editable: JIT
19
+ * provisioning toggles, expiry, auto-grant role, and allowed
20
+ * origins. Credential fields (`clientId`, `secretFingerprint`) are
21
+ * read-only. "Save" submits the update; "Cancel" discards changes.
22
+ *
23
+ * Secret rotation triggers `onSecretRotated` with the full
24
+ * {@link PlatformClientCreateResponse} so the parent can show the
25
+ * one-time secret alert.
26
+ *
27
+ * All visual properties flow through `--stgm-*` design tokens.
28
+ *
29
+ * @example
30
+ * ```tsx
31
+ * <PlatformClientDetailPanel
32
+ * platformClient={pc}
33
+ * onUpdated={(updated) => refetch()}
34
+ * onSecretRotated={(resp) => setFlow({ phase: "revealing", resp })}
35
+ * onDeleted={() => setFlow({ phase: "idle" })}
36
+ * onBack={() => setFlow({ phase: "idle" })}
37
+ * />
38
+ * ```
39
+ */
40
+ export function PlatformClientDetailPanel({ platformClient, onUpdated, onSecretRotated, onDeleted, onBack, className, }) {
41
+ const spec = platformClient.spec;
42
+ const meta = platformClient.metadata;
43
+ const { update, isUpdating, error: updateError, clearError: clearUpdateError } = useUpdatePlatformClient();
44
+ const { rotateSecret, isRotating, error: rotateError, clearError: clearRotateError } = useRotatePlatformClientSecret();
45
+ const { deletePlatformClient, isDeleting, error: deleteError } = useDeletePlatformClient();
46
+ const [mode, setMode] = useState("view");
47
+ const [confirmingDelete, setConfirmingDelete] = useState(false);
48
+ const [confirmingRotate, setConfirmingRotate] = useState(false);
49
+ const isBusy = isUpdating || isRotating || isDeleting;
50
+ // Edit form state
51
+ const [neverExpires, setNeverExpires] = useState(spec?.neverExpires ?? true);
52
+ const [expiresAt, setExpiresAt] = useState(() => {
53
+ if (spec?.expiresAt) {
54
+ return toDatetimeLocalValue(timestampDate(spec.expiresAt));
55
+ }
56
+ return "";
57
+ });
58
+ const [autoProvision, setAutoProvision] = useState(spec?.autoProvisionAccounts ?? false);
59
+ const [autoGrant, setAutoGrant] = useState(spec?.autoGrantOnOrg ?? false);
60
+ const [autoGrantRole, setAutoGrantRole] = useState(spec?.autoGrantRole ?? IamRole.iam_role_unspecified);
61
+ const [origins, setOrigins] = useState([...(spec?.allowedOrigins ?? [])]);
62
+ const [originInput, setOriginInput] = useState("");
63
+ const handleAutoProvisionChange = useCallback((v) => {
64
+ setAutoProvision(v);
65
+ if (!v) {
66
+ setAutoGrant(false);
67
+ setAutoGrantRole(IamRole.iam_role_unspecified);
68
+ }
69
+ }, []);
70
+ const handleAutoGrantChange = useCallback((v) => {
71
+ setAutoGrant(v);
72
+ if (v)
73
+ setAutoProvision(true);
74
+ if (!v)
75
+ setAutoGrantRole(IamRole.iam_role_unspecified);
76
+ }, []);
77
+ const addOrigin = useCallback(() => {
78
+ const trimmed = originInput.trim();
79
+ if (trimmed && !origins.includes(trimmed)) {
80
+ setOrigins((prev) => [...prev, trimmed]);
81
+ }
82
+ setOriginInput("");
83
+ }, [originInput, origins]);
84
+ const handleOriginKeyDown = useCallback((e) => {
85
+ if (e.key === "Enter") {
86
+ e.preventDefault();
87
+ addOrigin();
88
+ }
89
+ }, [addOrigin]);
90
+ const removeOrigin = useCallback((origin) => {
91
+ setOrigins((prev) => prev.filter((o) => o !== origin));
92
+ }, []);
93
+ const enterEdit = useCallback(() => {
94
+ setNeverExpires(spec?.neverExpires ?? true);
95
+ setExpiresAt(spec?.expiresAt
96
+ ? toDatetimeLocalValue(timestampDate(spec.expiresAt))
97
+ : "");
98
+ setAutoProvision(spec?.autoProvisionAccounts ?? false);
99
+ setAutoGrant(spec?.autoGrantOnOrg ?? false);
100
+ setAutoGrantRole(spec?.autoGrantRole ?? IamRole.iam_role_unspecified);
101
+ setOrigins([...(spec?.allowedOrigins ?? [])]);
102
+ setOriginInput("");
103
+ clearUpdateError();
104
+ setMode("edit");
105
+ }, [spec, clearUpdateError]);
106
+ const cancelEdit = useCallback(() => {
107
+ clearUpdateError();
108
+ setMode("view");
109
+ }, [clearUpdateError]);
110
+ const handleSave = useCallback(async (e) => {
111
+ e.preventDefault();
112
+ clearUpdateError();
113
+ try {
114
+ const updated = await update({
115
+ name: meta?.name ?? "",
116
+ slug: meta?.slug,
117
+ org: meta?.org ?? "",
118
+ neverExpires,
119
+ ...(!neverExpires &&
120
+ expiresAt && {
121
+ expiresAt: new Date(expiresAt).toISOString(),
122
+ }),
123
+ autoProvisionAccounts: autoProvision,
124
+ autoGrantOnOrg: autoGrant,
125
+ ...(autoGrant &&
126
+ autoGrantRole !== IamRole.iam_role_unspecified && {
127
+ autoGrantRole,
128
+ }),
129
+ allowedOrigins: origins,
130
+ });
131
+ setMode("view");
132
+ onUpdated?.(updated);
133
+ }
134
+ catch {
135
+ // error state is managed by useUpdatePlatformClient
136
+ }
137
+ }, [
138
+ meta,
139
+ neverExpires,
140
+ expiresAt,
141
+ autoProvision,
142
+ autoGrant,
143
+ autoGrantRole,
144
+ origins,
145
+ update,
146
+ clearUpdateError,
147
+ onUpdated,
148
+ ]);
149
+ const handleRotateSecret = useCallback(async () => {
150
+ clearRotateError();
151
+ try {
152
+ const response = await rotateSecret(meta?.id ?? "");
153
+ setConfirmingRotate(false);
154
+ onSecretRotated?.(response);
155
+ }
156
+ catch {
157
+ // error state is managed by the hook
158
+ }
159
+ }, [meta?.id, rotateSecret, clearRotateError, onSecretRotated]);
160
+ const handleDelete = useCallback(async () => {
161
+ try {
162
+ await deletePlatformClient({ resourceId: meta?.id ?? "" });
163
+ onDeleted?.();
164
+ }
165
+ catch {
166
+ // error state is surfaced via the hook
167
+ }
168
+ }, [meta?.id, deletePlatformClient, onDeleted]);
169
+ const createdAt = platformClient.status?.audit?.specAudit?.createdAt;
170
+ const updatedAt = platformClient.status?.audit?.specAudit?.updatedAt;
171
+ return (_jsxs("div", { className: cn("space-y-4", className), children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [onBack && (_jsxs("button", { type: "button", onClick: onBack, className: "text-muted-foreground hover:text-foreground mb-1 flex items-center gap-1 text-xs transition-colors", children: [_jsx(ArrowLeftIcon, {}), "Back to list"] })), _jsx("h3", { className: "text-foreground truncate text-sm font-semibold", children: meta?.name ?? "Platform Client" }), _jsxs("div", { className: "flex items-center gap-2", children: [meta?.slug && (_jsx("span", { className: "text-muted-foreground font-mono text-xs", children: meta.slug })), spec?.autoProvisionAccounts && (_jsx("span", { className: "inline-flex items-center rounded-full border border-primary/30 bg-primary-subtle px-2 py-0.5 text-[0.65rem] font-medium text-primary", children: "JIT" }))] })] }), mode === "view" && (_jsx("button", { type: "button", onClick: enterEdit, className: cn("shrink-0 rounded-md px-2.5 py-1.5 text-xs font-medium", "text-muted-foreground hover:text-foreground hover:bg-accent/50", "transition-colors"), children: "Edit" }))] }), mode === "view" ? (_jsx(ViewMode, { spec: spec, createdAt: createdAt, updatedAt: updatedAt })) : (_jsxs("form", { onSubmit: handleSave, className: "space-y-3", children: [_jsxs("div", { className: "rounded-md border border-border/60 bg-muted/30 px-3 py-2 space-y-1", children: [_jsx("p", { className: "text-[0.65rem] font-medium text-muted-foreground", children: "Client ID" }), _jsx("p", { className: "font-mono text-xs text-foreground", children: spec?.clientId ?? "—" })] }), _jsxs("fieldset", { className: "space-y-2", disabled: isUpdating, children: [_jsx("legend", { className: "text-xs font-medium text-foreground", children: "Expiry" }), _jsx(ToggleSwitch, { checked: neverExpires, onChange: setNeverExpires, label: "Never expires", disabled: isUpdating }), !neverExpires && (_jsxs("div", { className: "space-y-1", children: [_jsx("label", { htmlFor: "stgm-pc-edit-expires-at", className: "text-xs font-medium text-foreground", children: "Expires at" }), _jsx("input", { id: "stgm-pc-edit-expires-at", type: "datetime-local", value: expiresAt, onChange: (e) => setExpiresAt(e.target.value), disabled: isUpdating, className: cn("w-full rounded-md border border-input bg-background px-2.5 py-1.5 text-xs text-foreground", "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring", "disabled:pointer-events-none disabled:opacity-50") })] }))] }), _jsxs("fieldset", { className: "space-y-2.5", disabled: isUpdating, children: [_jsx("hr", { className: "border-border/40" }), _jsx("legend", { className: "text-xs font-medium text-foreground", children: "JIT provisioning" }), _jsx(ToggleSwitch, { checked: autoProvision, onChange: handleAutoProvisionChange, label: "Auto-provision accounts", hint: "Create a Stigmer identity account automatically on first token mint", disabled: isUpdating }), _jsx(ToggleSwitch, { checked: autoGrant, onChange: handleAutoGrantChange, label: "Auto-grant on organization", hint: "Grant a role on the owning organization when an account is provisioned", disabled: isUpdating || !autoProvision }), autoGrant && (_jsxs("div", { className: "space-y-1", children: [_jsx("label", { htmlFor: "stgm-pc-edit-grant-role", className: "text-xs font-medium text-foreground", children: "Auto-grant role" }), _jsx("select", { id: "stgm-pc-edit-grant-role", value: String(autoGrantRole), onChange: (e) => setAutoGrantRole(Number(e.target.value)), disabled: isUpdating, className: cn("w-full rounded-md border border-input bg-background px-2.5 py-1.5 text-xs text-foreground", "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring", "disabled:pointer-events-none disabled:opacity-50"), children: JIT_ROLE_OPTIONS.map((opt) => (_jsx("option", { value: opt.value, children: opt.label }, opt.value))) })] }))] }), _jsxs("fieldset", { className: "space-y-2", disabled: isUpdating, children: [_jsx("hr", { className: "border-border/40" }), _jsx("legend", { className: "text-xs font-medium text-foreground", children: "Allowed origins" }), _jsx("p", { className: "text-[0.65rem] text-muted-foreground", children: "Browser origins permitted to use tokens minted by this client. Leave empty to allow all origins." }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("input", { type: "text", value: originInput, onChange: (e) => setOriginInput(e.target.value), onKeyDown: handleOriginKeyDown, onBlur: () => {
172
+ if (originInput.trim())
173
+ addOrigin();
174
+ }, placeholder: "https://example.com", disabled: isUpdating, className: cn("min-w-0 flex-1 rounded-md border border-input bg-background px-2.5 py-1.5 text-xs text-foreground", "placeholder:text-muted-foreground", "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring", "disabled:pointer-events-none disabled:opacity-50") }), _jsx("button", { type: "button", onClick: addOrigin, disabled: isUpdating || !originInput.trim(), className: cn("shrink-0 rounded-md px-2.5 py-1.5 text-xs font-medium", "text-muted-foreground hover:text-foreground hover:bg-accent/50", "disabled:pointer-events-none disabled:opacity-50", "transition-colors"), children: "Add" })] }), origins.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-1.5", children: origins.map((origin) => (_jsxs("span", { className: "inline-flex items-center gap-1 rounded-full border border-border/60 bg-muted/40 px-2 py-0.5 text-[0.65rem] font-mono text-foreground", children: [origin, _jsx("button", { type: "button", onClick: () => removeOrigin(origin), disabled: isUpdating, "aria-label": `Remove ${origin}`, className: "text-muted-foreground hover:text-destructive transition-colors", children: _jsx(XIcon, {}) })] }, origin))) }))] }), updateError && (_jsx("p", { className: "text-destructive text-[0.65rem]", role: "alert", children: getUserMessage(updateError) })), _jsxs("div", { className: "flex items-center gap-2 pt-1", children: [_jsxs("button", { type: "submit", disabled: isUpdating, className: cn("inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium", "bg-primary text-primary-foreground hover:bg-primary/90", "disabled:pointer-events-none disabled:opacity-40"), children: [isUpdating && _jsx(SpinnerIcon, {}), "Save changes"] }), _jsx("button", { type: "button", onClick: cancelEdit, disabled: isUpdating, className: cn("rounded-md px-2.5 py-1.5 text-xs", "text-muted-foreground hover:text-foreground hover:bg-accent/50", "disabled:pointer-events-none disabled:opacity-50"), children: "Cancel" })] })] })), mode === "view" && (_jsxs("div", { className: "space-y-2 pt-2", children: [_jsx("hr", { className: "border-border/40" }), confirmingRotate ? (_jsxs("div", { className: "flex items-center justify-between rounded-md border border-warning/30 bg-warning/5 px-3 py-2", children: [_jsxs("p", { className: "text-xs text-foreground", children: ["Rotate secret? The current secret will be", _jsx("span", { className: "font-medium", children: " permanently invalidated" }), "."] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1.5", children: [_jsxs("button", { type: "button", onClick: handleRotateSecret, disabled: isBusy, className: cn("inline-flex items-center gap-1 rounded-md px-2.5 py-1 text-xs font-medium", "bg-primary text-primary-foreground hover:bg-primary/90", "disabled:pointer-events-none disabled:opacity-50"), children: [isRotating && _jsx(SpinnerIcon, {}), "Rotate"] }), _jsx("button", { type: "button", onClick: () => {
175
+ setConfirmingRotate(false);
176
+ clearRotateError();
177
+ }, disabled: isBusy, className: cn("rounded-md px-2.5 py-1 text-xs", "text-muted-foreground hover:text-foreground hover:bg-accent/50", "disabled:pointer-events-none disabled:opacity-50"), children: "Cancel" })] })] })) : (_jsx("button", { type: "button", onClick: () => setConfirmingRotate(true), disabled: isBusy, className: cn("rounded-md px-2.5 py-1.5 text-xs font-medium", "text-muted-foreground hover:text-foreground hover:bg-accent/50", "disabled:pointer-events-none disabled:opacity-50", "transition-colors"), children: "Rotate secret" })), rotateError && (_jsx("p", { className: "text-destructive text-[0.65rem]", role: "alert", children: getUserMessage(rotateError) })), confirmingDelete ? (_jsxs("div", { className: "flex items-center justify-between rounded-md border border-destructive/30 bg-destructive/5 px-3 py-2", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("p", { className: "text-xs text-foreground", children: ["Delete", " ", _jsx("span", { className: "font-medium", children: meta?.name }), "? This action is permanent."] }), deleteError && (_jsx("p", { className: "mt-0.5 text-[0.65rem] text-destructive", children: getUserMessage(deleteError) }))] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1.5", children: [_jsxs("button", { type: "button", onClick: handleDelete, disabled: isBusy, className: cn("inline-flex items-center gap-1 rounded-md px-2.5 py-1 text-xs font-medium", "bg-destructive text-destructive-foreground hover:bg-destructive/90", "disabled:pointer-events-none disabled:opacity-50"), children: [isDeleting && _jsx(SpinnerIcon, {}), "Delete"] }), _jsx("button", { type: "button", onClick: () => setConfirmingDelete(false), disabled: isBusy, className: cn("rounded-md px-2.5 py-1 text-xs", "text-muted-foreground hover:text-foreground hover:bg-accent/50", "disabled:pointer-events-none disabled:opacity-50"), children: "Cancel" })] })] })) : (_jsx("button", { type: "button", onClick: () => setConfirmingDelete(true), disabled: isBusy, className: cn("rounded-md px-2.5 py-1.5 text-xs font-medium", "text-destructive hover:text-destructive-foreground hover:bg-destructive/90", "disabled:pointer-events-none disabled:opacity-50", "transition-colors"), children: "Delete platform client" }))] }))] }));
178
+ }
179
+ // ---------------------------------------------------------------------------
180
+ // View mode
181
+ // ---------------------------------------------------------------------------
182
+ function ViewMode({ spec, createdAt, updatedAt, }) {
183
+ return (_jsxs("dl", { className: "space-y-2.5", children: [_jsx(Field, { label: "Client ID", value: spec?.clientId, mono: true }), _jsx(Field, { label: "Secret fingerprint", value: spec?.secretFingerprint
184
+ ? `••••${spec.secretFingerprint.slice(-4)}`
185
+ : undefined, mono: true }), spec?.neverExpires ? (_jsx(Field, { label: "Expiry", value: "Never expires" })) : spec?.expiresAt ? (_jsx(Field, { label: "Expires", value: formatDate(timestampDate(spec.expiresAt)) })) : null, _jsx("hr", { className: "border-border/40" }), _jsx(Field, { label: "Auto-provision accounts", value: spec?.autoProvisionAccounts ? "Enabled" : "Disabled" }), _jsx(Field, { label: "Auto-grant on organization", value: spec?.autoGrantOnOrg ? "Enabled" : "Disabled" }), spec?.autoGrantOnOrg && (_jsx(Field, { label: "Auto-grant role", value: formatIamRole(spec.autoGrantRole) })), (spec?.allowedOrigins.length ?? 0) > 0 && (_jsxs(_Fragment, { children: [_jsx("hr", { className: "border-border/40" }), _jsxs("div", { children: [_jsx("dt", { className: "text-muted-foreground text-[0.65rem] font-medium", children: "Allowed origins" }), _jsx("dd", { className: "mt-0.5 flex flex-wrap gap-1.5", children: spec.allowedOrigins.map((origin) => (_jsx("span", { className: "inline-block rounded-full border border-border/60 bg-muted/40 px-2 py-0.5 text-[0.65rem] font-mono text-foreground", children: origin }, origin))) })] })] })), _jsxs("div", { className: "flex gap-6", children: [createdAt && (_jsx(Field, { label: "Created", value: formatDate(timestampDate(createdAt)) })), updatedAt && (_jsx(Field, { label: "Updated", value: formatDate(timestampDate(updatedAt)) }))] })] }));
186
+ }
187
+ // ---------------------------------------------------------------------------
188
+ // Shared primitives
189
+ // ---------------------------------------------------------------------------
190
+ function Field({ label, value, mono, }) {
191
+ if (!value)
192
+ return null;
193
+ return (_jsxs("div", { children: [_jsx("dt", { className: "text-muted-foreground text-[0.65rem] font-medium", children: label }), _jsx("dd", { className: cn("text-foreground mt-0.5 break-all text-xs", mono && "font-mono"), children: value })] }));
194
+ }
195
+ function ToggleSwitch({ checked, onChange, label, hint, disabled, }) {
196
+ return (_jsxs("div", { className: "space-y-0.5", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { type: "button", role: "switch", "aria-checked": checked, onClick: () => onChange(!checked), disabled: disabled, className: cn("relative inline-flex h-5 w-9 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors", checked ? "bg-primary" : "bg-muted", "disabled:pointer-events-none disabled:opacity-50"), children: _jsx("span", { className: cn("pointer-events-none inline-block h-4 w-4 rounded-full bg-background shadow-sm ring-0 transition-transform", checked ? "translate-x-4" : "translate-x-0") }) }), _jsx("span", { className: "text-xs font-medium text-foreground", children: label })] }), hint && (_jsx("p", { className: "pl-11 text-[0.65rem] text-muted-foreground", children: hint }))] }));
197
+ }
198
+ // ---------------------------------------------------------------------------
199
+ // Constants
200
+ // ---------------------------------------------------------------------------
201
+ const JIT_ROLE_OPTIONS = [
202
+ { value: String(IamRole.iam_role_unspecified), label: "Default (viewer)" },
203
+ { value: String(IamRole.viewer), label: "Viewer" },
204
+ { value: String(IamRole.member), label: "Member" },
205
+ { value: String(IamRole.admin), label: "Admin" },
206
+ ];
207
+ // ---------------------------------------------------------------------------
208
+ // Helpers
209
+ // ---------------------------------------------------------------------------
210
+ function formatIamRole(role) {
211
+ switch (role) {
212
+ case IamRole.viewer:
213
+ return "Viewer";
214
+ case IamRole.member:
215
+ return "Member";
216
+ case IamRole.admin:
217
+ return "Admin";
218
+ case IamRole.owner:
219
+ return "Owner";
220
+ default:
221
+ return "Viewer (default)";
222
+ }
223
+ }
224
+ function formatDate(date) {
225
+ return date.toLocaleDateString(undefined, {
226
+ month: "short",
227
+ day: "numeric",
228
+ year: "numeric",
229
+ });
230
+ }
231
+ function toDatetimeLocalValue(date) {
232
+ const pad = (n) => String(n).padStart(2, "0");
233
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}`;
234
+ }
235
+ // ---------------------------------------------------------------------------
236
+ // Icons
237
+ // ---------------------------------------------------------------------------
238
+ function XIcon() {
239
+ return (_jsx("svg", { width: "10", height: "10", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": "true", children: _jsx("path", { d: "M4 4l8 8M12 4l-8 8" }) }));
240
+ }
241
+ function ArrowLeftIcon() {
242
+ return (_jsx("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: _jsx("path", { d: "M10 3L5 8l5 5" }) }));
243
+ }
244
+ function SpinnerIcon() {
245
+ return (_jsx("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", className: "animate-spin", "aria-hidden": "true", children: _jsx("path", { d: "M8 2a6 6 0 1 0 6 6" }) }));
246
+ }
247
+ //# sourceMappingURL=PlatformClientDetailPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlatformClientDetailPanel.js","sourceRoot":"","sources":["../../src/platform-client/PlatformClientDetailPanel.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import type { PlatformClient } from "@stigmer/protos/ai/stigmer/iam/platformclient/v1/api_pb";
2
+ /** Props for {@link PlatformClientListPanel}. */
3
+ export interface PlatformClientListPanelProps {
4
+ /** Organization slug whose platform clients should be listed. */
5
+ readonly org: string;
6
+ /** Fired when the user wants to edit a platform client. */
7
+ readonly onEdit?: (pc: PlatformClient) => void;
8
+ /** Expose the refetch function so parents can trigger a list refresh. */
9
+ readonly onRefetchRef?: (refetch: () => void) => void;
10
+ /** Additional CSS class names for the root container. */
11
+ readonly className?: string;
12
+ }
13
+ /**
14
+ * Displays a list of {@link PlatformClient} resources for an
15
+ * organization with inline delete confirmation.
16
+ *
17
+ * Each row shows the client name, `client_id` (monospace), secret
18
+ * fingerprint, expiry status, and creation date. A delete button
19
+ * triggers an inline confirmation flow.
20
+ *
21
+ * Platform clients are admin-level resources with small cardinality
22
+ * (typically 1–5 per org), so the list is rendered without pagination.
23
+ *
24
+ * All visual properties flow through `--stgm-*` design tokens.
25
+ *
26
+ * @example
27
+ * ```tsx
28
+ * <PlatformClientListPanel org="acme" />
29
+ * ```
30
+ *
31
+ * @example
32
+ * ```tsx
33
+ * <PlatformClientListPanel
34
+ * org="acme"
35
+ * onEdit={(pc) => setFlow({ phase: "editing", platformClient: pc })}
36
+ * onRefetchRef={(refetch) => { listRefetchRef.current = refetch; }}
37
+ * />
38
+ * ```
39
+ */
40
+ export declare function PlatformClientListPanel({ org, onEdit, onRefetchRef, className, }: PlatformClientListPanelProps): import("react/jsx-runtime").JSX.Element;
41
+ //# sourceMappingURL=PlatformClientListPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlatformClientListPanel.d.ts","sourceRoot":"","sources":["../../src/platform-client/PlatformClientListPanel.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yDAAyD,CAAC;AAI9F,iDAAiD;AACjD,MAAM,WAAW,4BAA4B;IAC3C,iEAAiE;IACjE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,cAAc,KAAK,IAAI,CAAC;IAC/C,yEAAyE;IACzE,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACtD,yDAAyD;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,GAAG,EACH,MAAM,EACN,YAAY,EACZ,SAAS,GACV,EAAE,4BAA4B,2CAwE9B"}
@@ -0,0 +1,123 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useCallback, useState } from "react";
4
+ import { cn } from "@stigmer/theme";
5
+ import { getUserMessage } from "@stigmer/sdk";
6
+ import { timestampDate } from "@bufbuild/protobuf/wkt";
7
+ import { usePlatformClientList } from "./usePlatformClientList";
8
+ import { useDeletePlatformClient } from "./useDeletePlatformClient";
9
+ /**
10
+ * Displays a list of {@link PlatformClient} resources for an
11
+ * organization with inline delete confirmation.
12
+ *
13
+ * Each row shows the client name, `client_id` (monospace), secret
14
+ * fingerprint, expiry status, and creation date. A delete button
15
+ * triggers an inline confirmation flow.
16
+ *
17
+ * Platform clients are admin-level resources with small cardinality
18
+ * (typically 1–5 per org), so the list is rendered without pagination.
19
+ *
20
+ * All visual properties flow through `--stgm-*` design tokens.
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * <PlatformClientListPanel org="acme" />
25
+ * ```
26
+ *
27
+ * @example
28
+ * ```tsx
29
+ * <PlatformClientListPanel
30
+ * org="acme"
31
+ * onEdit={(pc) => setFlow({ phase: "editing", platformClient: pc })}
32
+ * onRefetchRef={(refetch) => { listRefetchRef.current = refetch; }}
33
+ * />
34
+ * ```
35
+ */
36
+ export function PlatformClientListPanel({ org, onEdit, onRefetchRef, className, }) {
37
+ const { platformClients, isLoading, error, refetch } = usePlatformClientList(org);
38
+ const [confirmingId, setConfirmingId] = useState(null);
39
+ if (onRefetchRef) {
40
+ onRefetchRef(refetch);
41
+ }
42
+ if (isLoading) {
43
+ return (_jsx("div", { className: cn("space-y-2", className), "aria-busy": "true", "aria-label": "Loading platform clients", children: Array.from({ length: 2 }, (_, i) => (_jsx("div", { className: "bg-muted/40 h-14 animate-pulse rounded-lg" }, i))) }));
44
+ }
45
+ if (error) {
46
+ return (_jsx("p", { className: cn("text-destructive text-xs", className), role: "alert", children: getUserMessage(error) }));
47
+ }
48
+ if (platformClients.length === 0) {
49
+ return (_jsx("p", { className: cn("text-muted-foreground py-4 text-center text-xs", className), children: "No platform clients configured." }));
50
+ }
51
+ return (_jsx("div", { className: cn("space-y-2", className), role: "list", "aria-label": "Platform clients", children: platformClients.map((pc) => {
52
+ const id = pc.metadata?.id ?? "";
53
+ return (_jsx(PlatformClientRow, { platformClient: pc, isConfirming: confirmingId === id, onEdit: onEdit ? () => onEdit(pc) : undefined, onConfirmDelete: () => setConfirmingId(id), onCancelDelete: () => setConfirmingId(null), onDeleted: () => {
54
+ setConfirmingId(null);
55
+ refetch();
56
+ } }, id));
57
+ }) }));
58
+ }
59
+ // ---------------------------------------------------------------------------
60
+ // PlatformClientRow (internal)
61
+ // ---------------------------------------------------------------------------
62
+ function PlatformClientRow({ platformClient, isConfirming, onEdit, onConfirmDelete, onCancelDelete, onDeleted, }) {
63
+ const { deletePlatformClient, isDeleting, error } = useDeletePlatformClient();
64
+ const id = platformClient.metadata?.id ?? "";
65
+ const spec = platformClient.spec;
66
+ const name = platformClient.metadata?.name ?? "Unnamed client";
67
+ const clientId = spec?.clientId ?? "";
68
+ const fingerprint = spec?.secretFingerprint ?? "";
69
+ const createdAt = platformClient.status?.audit?.specAudit?.createdAt;
70
+ const handleDelete = useCallback(async () => {
71
+ try {
72
+ await deletePlatformClient({ resourceId: id });
73
+ onDeleted();
74
+ }
75
+ catch {
76
+ // error state is surfaced via the hook
77
+ }
78
+ }, [id, deletePlatformClient, onDeleted]);
79
+ if (isConfirming) {
80
+ return (_jsxs("div", { role: "listitem", className: "flex items-center justify-between rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2.5", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("p", { className: "text-xs text-foreground", children: ["Delete ", _jsx("span", { className: "font-medium", children: name }), "?", clientId && (_jsxs("span", { className: "ml-1 text-muted-foreground", children: ["This will invalidate client ID", " ", _jsx("code", { className: "font-mono", children: clientId }), "."] }))] }), error && (_jsx("p", { className: "mt-0.5 text-[0.65rem] text-destructive", children: getUserMessage(error) }))] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1.5", children: [_jsxs("button", { type: "button", onClick: handleDelete, disabled: isDeleting, className: cn("inline-flex items-center gap-1 rounded-md px-2.5 py-1 text-xs font-medium", "bg-destructive text-destructive-foreground hover:bg-destructive/90", "disabled:pointer-events-none disabled:opacity-50"), children: [isDeleting && _jsx(SpinnerIcon, {}), "Delete"] }), _jsx("button", { type: "button", onClick: onCancelDelete, disabled: isDeleting, className: cn("rounded-md px-2.5 py-1 text-xs", "text-muted-foreground hover:text-foreground hover:bg-accent/50", "disabled:pointer-events-none disabled:opacity-50"), children: "Cancel" })] })] }));
81
+ }
82
+ return (_jsxs("div", { role: "listitem", className: "flex items-center gap-3 rounded-lg border border-border/60 px-3 py-2.5 hover:border-border transition-colors", children: [_jsx(KeyIcon, {}), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block truncate text-sm font-medium text-foreground", children: name }), clientId && (_jsx("span", { className: "block truncate text-xs text-muted-foreground font-mono", children: clientId }))] }), _jsxs("div", { className: "hidden sm:flex shrink-0 items-center gap-3 text-xs text-muted-foreground", children: [fingerprint && (_jsxs("span", { className: "font-mono", title: `Secret fingerprint: ${fingerprint}`, children: ["\u2022\u2022\u2022\u2022", fingerprint.slice(-4)] })), _jsx(ExpiryBadge, { spec: spec }), spec?.autoProvisionAccounts && (_jsx("span", { className: "inline-flex items-center rounded-full border border-primary/30 bg-primary-subtle px-2 py-0.5 text-[0.65rem] font-medium text-primary", children: "JIT" })), createdAt && (_jsx("span", { title: `Created ${timestampDate(createdAt).toISOString()}`, children: formatShortDate(timestampDate(createdAt)) }))] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [onEdit && (_jsx("button", { type: "button", onClick: onEdit, "aria-label": `Edit ${name}`, className: cn("shrink-0 rounded p-1", "text-muted-foreground hover:text-foreground hover:bg-accent/50", "transition-colors"), children: _jsx(PencilIcon, {}) })), _jsx("button", { type: "button", onClick: onConfirmDelete, "aria-label": `Delete ${name}`, className: cn("shrink-0 rounded p-1", "text-muted-foreground hover:text-destructive hover:bg-destructive/10", "transition-colors"), children: _jsx(TrashIcon, {}) })] })] }));
83
+ }
84
+ // ---------------------------------------------------------------------------
85
+ // ExpiryBadge (internal)
86
+ // ---------------------------------------------------------------------------
87
+ function ExpiryBadge({ spec }) {
88
+ if (spec?.neverExpires) {
89
+ return (_jsx("span", { className: "text-[0.65rem] text-muted-foreground", children: "No expiry" }));
90
+ }
91
+ if (spec?.expiresAt) {
92
+ const date = timestampDate(spec.expiresAt);
93
+ const isExpired = date < new Date();
94
+ return (_jsx("span", { className: cn("text-[0.65rem]", isExpired ? "text-destructive font-medium" : "text-muted-foreground"), title: `Expires ${date.toISOString()}`, children: isExpired ? "Expired" : `Exp ${formatShortDate(date)}` }));
95
+ }
96
+ return null;
97
+ }
98
+ // ---------------------------------------------------------------------------
99
+ // Formatting helpers
100
+ // ---------------------------------------------------------------------------
101
+ function formatShortDate(date) {
102
+ return date.toLocaleDateString(undefined, {
103
+ month: "short",
104
+ day: "numeric",
105
+ year: "numeric",
106
+ });
107
+ }
108
+ // ---------------------------------------------------------------------------
109
+ // Icons
110
+ // ---------------------------------------------------------------------------
111
+ function KeyIcon() {
112
+ return (_jsxs("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", className: "shrink-0 text-muted-foreground", children: [_jsx("circle", { cx: "10.5", cy: "5.5", r: "3" }), _jsx("path", { d: "M8.5 7.5L3 13l-.5-2.5L5 10l1-1-1-1 3.5.5z" })] }));
113
+ }
114
+ function PencilIcon() {
115
+ return (_jsx("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: _jsx("path", { d: "M11 2.5l2.5 2.5L5 13.5H2.5V11L11 2.5z" }) }));
116
+ }
117
+ function TrashIcon() {
118
+ return (_jsxs("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("path", { d: "M2.5 4h11M5.5 4V2.5a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1V4" }), _jsx("path", { d: "M12.5 4v9a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1V4" }), _jsx("line", { x1: "6.5", y1: "7", x2: "6.5", y2: "11" }), _jsx("line", { x1: "9.5", y1: "7", x2: "9.5", y2: "11" })] }));
119
+ }
120
+ function SpinnerIcon() {
121
+ return (_jsx("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", className: "animate-spin", "aria-hidden": "true", children: _jsx("path", { d: "M8 2a6 6 0 1 0 6 6" }) }));
122
+ }
123
+ //# sourceMappingURL=PlatformClientListPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlatformClientListPanel.js","sourceRoot":"","sources":["../../src/platform-client/PlatformClientListPanel.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /** Props for {@link PlatformClientSecretAlert}. */
2
+ export interface PlatformClientSecretAlertProps {
3
+ /** The `client_id` to display alongside the secret for pairing context. */
4
+ readonly clientId: string;
5
+ /** The raw client secret value to display. Shown exactly once. */
6
+ readonly clientSecret: string;
7
+ /** Whether this alert follows a creation or a secret rotation. */
8
+ readonly context: "created" | "rotated";
9
+ /** Fired when the user dismisses the alert. */
10
+ readonly onDismiss: () => void;
11
+ /** Additional CSS class names for the root container. */
12
+ readonly className?: string;
13
+ }
14
+ /**
15
+ * One-time reveal component displayed after a platform client is
16
+ * created or its secret is rotated.
17
+ *
18
+ * Shows both the `client_id` (read-only, for context) and the raw
19
+ * `client_secret` with a **Copy** button. The secret is only
20
+ * available once — the server never returns it again — so this
21
+ * component prominently warns the user to copy it immediately.
22
+ *
23
+ * This is a standalone alert component, not a modal — the parent
24
+ * decides how to present and position it.
25
+ *
26
+ * All visual properties flow through `--stgm-*` design tokens.
27
+ *
28
+ * @example
29
+ * ```tsx
30
+ * <PlatformClientSecretAlert
31
+ * clientId="stgm_pc_abc123"
32
+ * clientSecret="stgm_secret_xyz..."
33
+ * context="created"
34
+ * onDismiss={() => setFlow({ phase: "idle" })}
35
+ * />
36
+ * ```
37
+ */
38
+ export declare function PlatformClientSecretAlert({ clientId, clientSecret, context, onDismiss, className, }: PlatformClientSecretAlertProps): import("react/jsx-runtime").JSX.Element;
39
+ //# sourceMappingURL=PlatformClientSecretAlert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlatformClientSecretAlert.d.ts","sourceRoot":"","sources":["../../src/platform-client/PlatformClientSecretAlert.tsx"],"names":[],"mappings":"AAKA,mDAAmD;AACnD,MAAM,WAAW,8BAA8B;IAC7C,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,kEAAkE;IAClE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,CAAC;IACxC,+CAA+C;IAC/C,QAAQ,CAAC,SAAS,EAAE,MAAM,IAAI,CAAC;IAC/B,yDAAyD;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAID;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,yBAAyB,CAAC,EACxC,QAAQ,EACR,YAAY,EACZ,OAAO,EACP,SAAS,EACT,SAAS,GACV,EAAE,8BAA8B,2CA2FhC"}
@@ -0,0 +1,74 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useCallback, useState } from "react";
4
+ import { cn } from "@stigmer/theme";
5
+ const COPIED_FEEDBACK_MS = 2000;
6
+ /**
7
+ * One-time reveal component displayed after a platform client is
8
+ * created or its secret is rotated.
9
+ *
10
+ * Shows both the `client_id` (read-only, for context) and the raw
11
+ * `client_secret` with a **Copy** button. The secret is only
12
+ * available once — the server never returns it again — so this
13
+ * component prominently warns the user to copy it immediately.
14
+ *
15
+ * This is a standalone alert component, not a modal — the parent
16
+ * decides how to present and position it.
17
+ *
18
+ * All visual properties flow through `--stgm-*` design tokens.
19
+ *
20
+ * @example
21
+ * ```tsx
22
+ * <PlatformClientSecretAlert
23
+ * clientId="stgm_pc_abc123"
24
+ * clientSecret="stgm_secret_xyz..."
25
+ * context="created"
26
+ * onDismiss={() => setFlow({ phase: "idle" })}
27
+ * />
28
+ * ```
29
+ */
30
+ export function PlatformClientSecretAlert({ clientId, clientSecret, context, onDismiss, className, }) {
31
+ const [copiedField, setCopiedField] = useState(null);
32
+ const handleCopy = useCallback(async (value, field) => {
33
+ try {
34
+ await navigator.clipboard.writeText(value);
35
+ setCopiedField(field);
36
+ setTimeout(() => setCopiedField(null), COPIED_FEEDBACK_MS);
37
+ }
38
+ catch {
39
+ const el = document.getElementById(field === "secret"
40
+ ? "stgm-pc-secret-reveal"
41
+ : "stgm-pc-client-id-reveal");
42
+ if (el) {
43
+ const selection = window.getSelection();
44
+ const range = document.createRange();
45
+ range.selectNodeContents(el);
46
+ selection?.removeAllRanges();
47
+ selection?.addRange(range);
48
+ }
49
+ }
50
+ }, []);
51
+ const title = context === "created"
52
+ ? "Platform client created"
53
+ : "Client secret rotated";
54
+ return (_jsxs("div", { role: "alert", className: cn("rounded-lg border border-primary/30 bg-primary-subtle p-4", className), children: [_jsxs("div", { className: "mb-3 flex items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "text-sm font-medium text-foreground", children: title }), _jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children: "Copy the client secret now. It will not be shown again." })] }), _jsx("button", { type: "button", onClick: onDismiss, "aria-label": "Dismiss", className: cn("shrink-0 rounded p-1", "text-muted-foreground hover:text-foreground hover:bg-accent/50", "transition-colors"), children: _jsx(CloseIcon, {}) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(CopyableField, { id: "stgm-pc-client-id-reveal", label: "Client ID", value: clientId, copied: copiedField === "id", onCopy: () => handleCopy(clientId, "id") }), _jsx(CopyableField, { id: "stgm-pc-secret-reveal", label: "Client secret", value: clientSecret, copied: copiedField === "secret", onCopy: () => handleCopy(clientSecret, "secret") })] }), _jsxs("div", { role: "status", "aria-live": "polite", "aria-atomic": "true", className: "sr-only", children: [copiedField === "id" && "Client ID copied to clipboard", copiedField === "secret" && "Client secret copied to clipboard"] })] }));
55
+ }
56
+ // ---------------------------------------------------------------------------
57
+ // CopyableField (internal)
58
+ // ---------------------------------------------------------------------------
59
+ function CopyableField({ id, label, value, copied, onCopy, }) {
60
+ return (_jsxs("div", { children: [_jsx("span", { className: "text-[0.65rem] font-medium text-muted-foreground", children: label }), _jsxs("div", { className: "mt-0.5 flex items-center gap-2", children: [_jsx("code", { id: id, className: cn("min-w-0 flex-1 select-all truncate rounded-md", "border border-input bg-background px-2.5 py-1.5", "font-mono text-xs text-foreground"), children: value }), _jsxs("button", { type: "button", onClick: onCopy, "aria-label": `Copy ${label}`, className: cn("inline-flex shrink-0 items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium", "bg-primary text-primary-foreground hover:bg-primary/90", "transition-colors"), children: [copied ? _jsx(CheckIcon, {}) : _jsx(CopyIcon, {}), copied ? "Copied" : "Copy"] })] })] }));
61
+ }
62
+ // ---------------------------------------------------------------------------
63
+ // Icons
64
+ // ---------------------------------------------------------------------------
65
+ function CopyIcon() {
66
+ return (_jsxs("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("rect", { x: "5", y: "5", width: "9", height: "9", rx: "1.5" }), _jsx("path", { d: "M5 11H3.5A1.5 1.5 0 0 1 2 9.5V3.5A1.5 1.5 0 0 1 3.5 2h6A1.5 1.5 0 0 1 11 3.5V5" })] }));
67
+ }
68
+ function CheckIcon() {
69
+ return (_jsx("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: _jsx("path", { d: "M3 8.5l3.5 3.5L13 5" }) }));
70
+ }
71
+ function CloseIcon() {
72
+ return (_jsx("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", "aria-hidden": "true", children: _jsx("path", { d: "M4 4l8 8M12 4l-8 8" }) }));
73
+ }
74
+ //# sourceMappingURL=PlatformClientSecretAlert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlatformClientSecretAlert.js","sourceRoot":"","sources":["../../src/platform-client/PlatformClientSecretAlert.tsx"],"names":[],"mappings":"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"}