@burdenoff/microfe-devportal 2026.608.1 → 2026.609.2

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 (93) hide show
  1. package/dist/devportal/DevportalRoutes.js +9 -5
  2. package/dist/devportal/DevportalRoutes.js.map +1 -1
  3. package/dist/devportal/hooks/useGraphQL.js +49 -36
  4. package/dist/devportal/hooks/useGraphQL.js.map +1 -1
  5. package/dist/devportal/pages/DashboardPage.js +152 -134
  6. package/dist/devportal/pages/DashboardPage.js.map +1 -1
  7. package/dist/devportal/pages/SetupPage.js +501 -0
  8. package/dist/devportal/pages/SetupPage.js.map +1 -0
  9. package/dist/devportal/pages/StoreSubmissionPage.js +98 -76
  10. package/dist/devportal/pages/StoreSubmissionPage.js.map +1 -1
  11. package/dist/node_modules/@apollo/client/link/core/ApolloLink.js +52 -0
  12. package/dist/node_modules/@apollo/client/link/core/ApolloLink.js.map +1 -0
  13. package/dist/node_modules/@apollo/client/link/subscriptions/index.js +41 -0
  14. package/dist/node_modules/@apollo/client/link/subscriptions/index.js.map +1 -0
  15. package/dist/node_modules/@apollo/client/link/utils/createOperation.js +34 -0
  16. package/dist/node_modules/@apollo/client/link/utils/createOperation.js.map +1 -0
  17. package/dist/node_modules/@apollo/client/utilities/caching/sizes.js +6 -0
  18. package/dist/node_modules/@apollo/client/utilities/caching/sizes.js.map +1 -0
  19. package/dist/node_modules/@apollo/client/utilities/graphql/print.js +16 -0
  20. package/dist/node_modules/@apollo/client/utilities/graphql/print.js.map +1 -0
  21. package/dist/node_modules/@apollo/client/utilities/internal/caches.js +19 -0
  22. package/dist/node_modules/@apollo/client/utilities/internal/caches.js.map +1 -0
  23. package/dist/node_modules/@apollo/client/utilities/internal/checkDocument.js +21 -0
  24. package/dist/node_modules/@apollo/client/utilities/internal/checkDocument.js.map +1 -0
  25. package/dist/node_modules/@apollo/client/utilities/internal/getMainDefinition.js +17 -0
  26. package/dist/node_modules/@apollo/client/utilities/internal/getMainDefinition.js.map +1 -0
  27. package/dist/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js +9 -0
  28. package/dist/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js.map +1 -0
  29. package/dist/node_modules/@apollo/client/utilities/internal/getOperationDefinition.js +9 -0
  30. package/dist/node_modules/@apollo/client/utilities/internal/getOperationDefinition.js.map +1 -0
  31. package/dist/node_modules/@apollo/client/utilities/internal/getOperationName.js +8 -0
  32. package/dist/node_modules/@apollo/client/utilities/internal/getOperationName.js.map +1 -0
  33. package/dist/node_modules/@apollo/client/utilities/internal/globals/global.js +9 -0
  34. package/dist/node_modules/@apollo/client/utilities/internal/globals/global.js.map +1 -0
  35. package/dist/node_modules/@apollo/client/utilities/internal/globals/maybe.js +10 -0
  36. package/dist/node_modules/@apollo/client/utilities/internal/globals/maybe.js.map +1 -0
  37. package/dist/node_modules/@apollo/client/utilities/internal/isNonNullObject.js +8 -0
  38. package/dist/node_modules/@apollo/client/utilities/internal/isNonNullObject.js.map +1 -0
  39. package/dist/node_modules/@apollo/client/utilities/internal/makeUniqueId.js +10 -0
  40. package/dist/node_modules/@apollo/client/utilities/internal/makeUniqueId.js.map +1 -0
  41. package/dist/node_modules/@apollo/client/utilities/internal/memoize.js +23 -0
  42. package/dist/node_modules/@apollo/client/utilities/internal/memoize.js.map +1 -0
  43. package/dist/node_modules/@apollo/client/utilities/internal/stringifyForDisplay.js +10 -0
  44. package/dist/node_modules/@apollo/client/utilities/internal/stringifyForDisplay.js.map +1 -0
  45. package/dist/node_modules/@apollo/client/utilities/invariant/index.js +57 -0
  46. package/dist/node_modules/@apollo/client/utilities/invariant/index.js.map +1 -0
  47. package/dist/node_modules/@apollo/client/version.js +6 -0
  48. package/dist/node_modules/@apollo/client/version.js.map +1 -0
  49. package/dist/node_modules/@wry/caches/lib/weak.js +67 -0
  50. package/dist/node_modules/@wry/caches/lib/weak.js.map +1 -0
  51. package/dist/node_modules/@wry/trie/lib/index.js +53 -0
  52. package/dist/node_modules/@wry/trie/lib/index.js.map +1 -0
  53. package/dist/node_modules/graphql-ws/dist/client.js +272 -0
  54. package/dist/node_modules/graphql-ws/dist/client.js.map +1 -0
  55. package/dist/node_modules/graphql-ws/dist/common-CGW11Fyb.js +62 -0
  56. package/dist/node_modules/graphql-ws/dist/common-CGW11Fyb.js.map +1 -0
  57. package/dist/node_modules/rxjs/dist/esm5/internal/NotificationFactories.js +21 -0
  58. package/dist/node_modules/rxjs/dist/esm5/internal/NotificationFactories.js.map +1 -0
  59. package/dist/node_modules/rxjs/dist/esm5/internal/Observable.js +78 -0
  60. package/dist/node_modules/rxjs/dist/esm5/internal/Observable.js.map +1 -0
  61. package/dist/node_modules/rxjs/dist/esm5/internal/Subscriber.js +117 -0
  62. package/dist/node_modules/rxjs/dist/esm5/internal/Subscriber.js.map +1 -0
  63. package/dist/node_modules/rxjs/dist/esm5/internal/Subscription.js +93 -0
  64. package/dist/node_modules/rxjs/dist/esm5/internal/Subscription.js.map +1 -0
  65. package/dist/node_modules/rxjs/dist/esm5/internal/config.js +12 -0
  66. package/dist/node_modules/rxjs/dist/esm5/internal/config.js.map +1 -0
  67. package/dist/node_modules/rxjs/dist/esm5/internal/observable/empty.js +9 -0
  68. package/dist/node_modules/rxjs/dist/esm5/internal/observable/empty.js.map +1 -0
  69. package/dist/node_modules/rxjs/dist/esm5/internal/scheduler/timeoutProvider.js +16 -0
  70. package/dist/node_modules/rxjs/dist/esm5/internal/scheduler/timeoutProvider.js.map +1 -0
  71. package/dist/node_modules/rxjs/dist/esm5/internal/symbol/observable.js +8 -0
  72. package/dist/node_modules/rxjs/dist/esm5/internal/symbol/observable.js.map +1 -0
  73. package/dist/node_modules/rxjs/dist/esm5/internal/util/UnsubscriptionError.js +13 -0
  74. package/dist/node_modules/rxjs/dist/esm5/internal/util/UnsubscriptionError.js.map +1 -0
  75. package/dist/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js +11 -0
  76. package/dist/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js.map +1 -0
  77. package/dist/node_modules/rxjs/dist/esm5/internal/util/createErrorClass.js +11 -0
  78. package/dist/node_modules/rxjs/dist/esm5/internal/util/createErrorClass.js.map +1 -0
  79. package/dist/node_modules/rxjs/dist/esm5/internal/util/errorContext.js +22 -0
  80. package/dist/node_modules/rxjs/dist/esm5/internal/util/errorContext.js.map +1 -0
  81. package/dist/node_modules/rxjs/dist/esm5/internal/util/identity.js +8 -0
  82. package/dist/node_modules/rxjs/dist/esm5/internal/util/identity.js.map +1 -0
  83. package/dist/node_modules/rxjs/dist/esm5/internal/util/isFunction.js +8 -0
  84. package/dist/node_modules/rxjs/dist/esm5/internal/util/isFunction.js.map +1 -0
  85. package/dist/node_modules/rxjs/dist/esm5/internal/util/noop.js +6 -0
  86. package/dist/node_modules/rxjs/dist/esm5/internal/util/noop.js.map +1 -0
  87. package/dist/node_modules/rxjs/dist/esm5/internal/util/pipe.js +13 -0
  88. package/dist/node_modules/rxjs/dist/esm5/internal/util/pipe.js.map +1 -0
  89. package/dist/node_modules/rxjs/dist/esm5/internal/util/reportUnhandledError.js +14 -0
  90. package/dist/node_modules/rxjs/dist/esm5/internal/util/reportUnhandledError.js.map +1 -0
  91. package/dist/node_modules/rxjs/node_modules/tslib/tslib.es6.js +52 -0
  92. package/dist/node_modules/rxjs/node_modules/tslib/tslib.es6.js.map +1 -0
  93. package/package.json +2 -1
@@ -0,0 +1,501 @@
1
+ import { useDevportal as e } from "../providers/DevportalProvider.js";
2
+ import { useDevportalEventBus as t } from "../events/index.js";
3
+ import { APP_TYPE_LABELS as n } from "../utils/constants.js";
4
+ import { InputField as r, SelectField as i, TextareaField as a } from "../components/FormField.js";
5
+ import { useCreateApplicationMutation as ee, useCreateOrganizationMutation as te } from "../../generated/global-operations.js";
6
+ import { useState as o } from "react";
7
+ import { useI18n as s } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
8
+ import { AppWindow as c, ArrowRight as ne, BookOpen as re, Building2 as l, Check as u, ChevronRight as d, Key as f, Rocket as p } from "lucide-react";
9
+ import { jsx as m, jsxs as h } from "react/jsx-runtime";
10
+ //#region src/devportal/pages/SetupPage.tsx
11
+ var g = [
12
+ {
13
+ value: "FREE",
14
+ label: "Free",
15
+ price: "Free",
16
+ apps: "1 app",
17
+ calls: "100K calls/mo"
18
+ },
19
+ {
20
+ value: "DEVELOPER",
21
+ label: "Developer",
22
+ price: "$29/mo",
23
+ apps: "3 apps",
24
+ calls: "1M calls/mo"
25
+ },
26
+ {
27
+ value: "PROFESSIONAL",
28
+ label: "Professional",
29
+ price: "$99/mo",
30
+ apps: "10 apps",
31
+ calls: "10M calls/mo"
32
+ }
33
+ ], _ = [{
34
+ value: "",
35
+ label: "Select type…"
36
+ }, ...Object.entries(n).map(([e, t]) => ({
37
+ value: e,
38
+ label: t
39
+ }))], v = [
40
+ {
41
+ value: "",
42
+ label: "Select category…"
43
+ },
44
+ {
45
+ value: "productivity",
46
+ label: "Productivity"
47
+ },
48
+ {
49
+ value: "communication",
50
+ label: "Communication"
51
+ },
52
+ {
53
+ value: "analytics",
54
+ label: "Analytics"
55
+ },
56
+ {
57
+ value: "automation",
58
+ label: "Automation"
59
+ },
60
+ {
61
+ value: "developer-tools",
62
+ label: "Developer Tools"
63
+ },
64
+ {
65
+ value: "finance",
66
+ label: "Finance"
67
+ },
68
+ {
69
+ value: "hr",
70
+ label: "HR & People"
71
+ },
72
+ {
73
+ value: "marketing",
74
+ label: "Marketing"
75
+ },
76
+ {
77
+ value: "project-management",
78
+ label: "Project Management"
79
+ },
80
+ {
81
+ value: "security",
82
+ label: "Security"
83
+ },
84
+ {
85
+ value: "support",
86
+ label: "Support"
87
+ },
88
+ {
89
+ value: "other",
90
+ label: "Other"
91
+ }
92
+ ];
93
+ function y(e) {
94
+ return e.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
95
+ }
96
+ function b() {
97
+ try {
98
+ localStorage.setItem("devportal_setup_dismissed", "1");
99
+ } catch {}
100
+ }
101
+ var x = [
102
+ {
103
+ key: "org",
104
+ label: "Organization"
105
+ },
106
+ {
107
+ key: "app",
108
+ label: "First app"
109
+ },
110
+ {
111
+ key: "done",
112
+ label: "Done"
113
+ }
114
+ ], ie = ({ current: e }) => {
115
+ let t = x.findIndex((t) => t.key === e);
116
+ return /* @__PURE__ */ m("div", {
117
+ className: "flex items-center gap-0",
118
+ children: x.map((e, n) => {
119
+ let r = n < t, i = n === t;
120
+ return /* @__PURE__ */ h("div", {
121
+ className: "flex items-center",
122
+ children: [/* @__PURE__ */ h("div", {
123
+ className: "flex flex-col items-center gap-1.5",
124
+ children: [/* @__PURE__ */ m("div", {
125
+ className: ["flex h-8 w-8 items-center justify-center rounded-full text-sm font-semibold transition-colors", r ? "bg-primary text-primary-foreground" : i ? "bg-primary text-primary-foreground ring-4 ring-primary/20" : "bg-muted text-muted-foreground"].join(" "),
126
+ children: r ? /* @__PURE__ */ m(u, { size: 14 }) : n + 1
127
+ }), /* @__PURE__ */ m("span", {
128
+ className: ["text-xs font-medium whitespace-nowrap", i ? "text-foreground" : "text-muted-foreground"].join(" "),
129
+ children: e.label
130
+ })]
131
+ }), n < x.length - 1 && /* @__PURE__ */ m("div", { className: ["mx-3 mb-5 h-px w-16 flex-shrink-0 transition-colors", n < t ? "bg-primary" : "bg-border"].join(" ") })]
132
+ }, e.key);
133
+ })
134
+ });
135
+ }, S = () => {
136
+ let { navigate: n, basePath: u } = e(), { t: x } = s(), S = t(), w = (e, t) => {
137
+ let n = x(e);
138
+ return n === e ? t : n;
139
+ }, T = (e) => n?.(`${u}${e}`), [E, D] = o("org"), [O, k] = o(null), [A, ae] = o(null), [j, M] = o(""), [N, P] = o(""), [F, oe] = o(""), [I, L] = o("FREE"), [R, z] = o({}), [B, { loading: V }] = te(), H = () => {
140
+ let e = {};
141
+ return j.trim() ? j.length < 2 && (e.name = w("devportal.orgNameTooShort", "Name must be at least 2 characters")) : e.name = w("devportal.orgNameRequired", "Organization name is required"), N.trim() ? /^[a-z0-9-]+$/.test(N) || (e.slug = w("devportal.slugInvalid", "Lowercase letters, numbers, and hyphens only")) : e.slug = w("devportal.slugRequired", "Slug is required"), z(e), Object.keys(e).length === 0;
142
+ }, U = async () => {
143
+ if (H()) try {
144
+ let e = (await B({ variables: { input: {
145
+ name: j,
146
+ slug: N || void 0,
147
+ description: F || void 0,
148
+ metadata: I === "FREE" ? void 0 : { tier: I }
149
+ } } })).data?.createDeveloperOrganization?.id;
150
+ e && (S.emit("devportal.org.created", {
151
+ organizationId: e,
152
+ name: j
153
+ }), k(e), D("app"));
154
+ } catch {}
155
+ }, [W, G] = o(""), [K, se] = o(""), [q, ce] = o(""), [J, le] = o(""), [Y, ue] = o(""), [X, Z] = o({}), [de, { loading: Q }] = ee(), fe = () => {
156
+ let e = {};
157
+ return W.trim() ? W.length < 3 && (e.name = w("devportal.nameTooShort", "Name must be at least 3 characters")) : e.name = w("devportal.appNameRequired", "Application name is required"), q || (e.appType = w("devportal.appTypeRequired", "Application type is required")), J || (e.category = w("devportal.categoryRequired", "Category is required")), Y.trim() || (e.shortDescription = w("devportal.shortDescriptionRequired", "Short description is required")), Z(e), Object.keys(e).length === 0;
158
+ }, pe = async () => {
159
+ if (fe()) try {
160
+ let e = (await de({ variables: { input: {
161
+ name: W,
162
+ slug: K || void 0,
163
+ appType: q,
164
+ category: J || void 0,
165
+ shortDescription: Y || void 0,
166
+ visibility: "PRIVATE",
167
+ developerOrganizationId: O || void 0
168
+ } } })).data?.createApplication?.id;
169
+ e && (S.emit("devportal.app.created", {
170
+ appId: e,
171
+ name: W,
172
+ appType: q,
173
+ organizationId: O
174
+ }), ae(e), b(), D("done"));
175
+ } catch {}
176
+ }, $ = () => {
177
+ b(), T("/");
178
+ };
179
+ return /* @__PURE__ */ h("main", {
180
+ className: "min-h-screen bg-surface-default",
181
+ children: [/* @__PURE__ */ m("div", {
182
+ className: "border-b border-border-default bg-surface-raised",
183
+ children: /* @__PURE__ */ m("div", {
184
+ className: "mx-auto max-w-2xl px-6 py-5",
185
+ children: /* @__PURE__ */ h("div", {
186
+ className: "flex items-center justify-between",
187
+ children: [/* @__PURE__ */ h("div", {
188
+ className: "flex items-center gap-3",
189
+ children: [/* @__PURE__ */ m("div", {
190
+ className: "flex h-9 w-9 items-center justify-center rounded-lg bg-primary/10 text-primary",
191
+ children: /* @__PURE__ */ m(p, { size: 20 })
192
+ }), /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("p", {
193
+ className: "text-xs font-medium text-muted-foreground",
194
+ children: w("devportal.developerPortal", "Developer Portal")
195
+ }), /* @__PURE__ */ m("h1", {
196
+ className: "text-base font-semibold text-foreground",
197
+ children: w("devportal.setup.title", "Get set up")
198
+ })] })]
199
+ }), E !== "done" && /* @__PURE__ */ m("button", {
200
+ type: "button",
201
+ onClick: $,
202
+ className: "text-sm text-muted-foreground hover:text-foreground transition-colors",
203
+ children: w("devportal.setup.skipForNow", "Skip for now")
204
+ })]
205
+ })
206
+ })
207
+ }), /* @__PURE__ */ h("div", {
208
+ className: "mx-auto max-w-2xl px-6 py-10",
209
+ children: [
210
+ /* @__PURE__ */ m("div", {
211
+ className: "mb-10 flex justify-center",
212
+ children: /* @__PURE__ */ m(ie, { current: E })
213
+ }),
214
+ E === "org" && /* @__PURE__ */ h("div", {
215
+ className: "rounded-xl border border-border-default bg-surface-raised p-8 shadow-sm",
216
+ children: [
217
+ /* @__PURE__ */ h("div", {
218
+ className: "mb-6 flex items-center gap-3",
219
+ children: [/* @__PURE__ */ m("div", {
220
+ className: "flex h-10 w-10 items-center justify-center rounded-lg bg-primary/10 text-primary",
221
+ children: /* @__PURE__ */ m(l, { size: 20 })
222
+ }), /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("h2", {
223
+ className: "text-lg font-semibold text-foreground",
224
+ children: w("devportal.setup.orgTitle", "Set up your organization")
225
+ }), /* @__PURE__ */ m("p", {
226
+ className: "text-sm text-muted-foreground",
227
+ children: w("devportal.setup.orgSubtitle", "This groups your apps and teams under one publisher identity.")
228
+ })] })]
229
+ }),
230
+ /* @__PURE__ */ h("div", {
231
+ className: "space-y-5",
232
+ children: [
233
+ /* @__PURE__ */ m(r, {
234
+ label: w("devportal.organizationName", "Organization Name"),
235
+ value: j,
236
+ onChange: (e) => {
237
+ M(e.target.value), (!N || N === y(j)) && P(y(e.target.value)), z((e) => ({
238
+ ...e,
239
+ name: void 0
240
+ }));
241
+ },
242
+ placeholder: w("devportal.organizationNamePlaceholder", "Acme Development"),
243
+ required: !0,
244
+ error: R.name
245
+ }),
246
+ /* @__PURE__ */ m(r, {
247
+ label: w("devportal.slug", "Slug"),
248
+ value: N,
249
+ onChange: (e) => {
250
+ P(e.target.value.toLowerCase()), z((e) => ({
251
+ ...e,
252
+ slug: void 0
253
+ }));
254
+ },
255
+ placeholder: "acme-dev",
256
+ required: !0,
257
+ error: R.slug,
258
+ hint: w("devportal.slugHint", "URL-friendly identifier — auto-generated from name")
259
+ }),
260
+ /* @__PURE__ */ m(a, {
261
+ label: w("devportal.description", "Description"),
262
+ value: F,
263
+ onChange: (e) => oe(e.target.value),
264
+ placeholder: w("devportal.orgDescriptionPlaceholder", "Tell us about your organization…"),
265
+ rows: 2
266
+ }),
267
+ /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("p", {
268
+ className: "mb-2 text-sm font-medium text-foreground",
269
+ children: w("devportal.selectPlan", "Select Plan")
270
+ }), /* @__PURE__ */ m("div", {
271
+ className: "grid grid-cols-3 gap-3",
272
+ children: g.map((e) => /* @__PURE__ */ h("button", {
273
+ type: "button",
274
+ onClick: () => L(e.value),
275
+ className: ["rounded-lg border p-3 text-left text-sm transition-colors", I === e.value ? "border-primary bg-primary/5 ring-2 ring-primary" : "border-border-default hover:border-muted-foreground/50"].join(" "),
276
+ children: [
277
+ /* @__PURE__ */ m("p", {
278
+ className: "font-semibold text-foreground",
279
+ children: e.label
280
+ }),
281
+ /* @__PURE__ */ m("p", {
282
+ className: "mt-0.5 text-xs text-primary",
283
+ children: e.price
284
+ }),
285
+ /* @__PURE__ */ m("p", {
286
+ className: "mt-1.5 text-xs text-muted-foreground",
287
+ children: e.apps
288
+ }),
289
+ /* @__PURE__ */ m("p", {
290
+ className: "text-xs text-muted-foreground",
291
+ children: e.calls
292
+ })
293
+ ]
294
+ }, e.value))
295
+ })] })
296
+ ]
297
+ }),
298
+ /* @__PURE__ */ h("div", {
299
+ className: "mt-8 flex items-center justify-between border-t border-border-default pt-6",
300
+ children: [/* @__PURE__ */ m("button", {
301
+ type: "button",
302
+ onClick: $,
303
+ className: "text-sm text-muted-foreground hover:text-foreground transition-colors",
304
+ children: w("devportal.setup.skipForNow", "Skip for now")
305
+ }), /* @__PURE__ */ h("button", {
306
+ type: "button",
307
+ onClick: () => void U(),
308
+ disabled: V,
309
+ className: "inline-flex items-center gap-2 rounded-lg bg-primary px-5 py-2.5 text-sm font-semibold text-primary-foreground hover:bg-primary/90 disabled:opacity-60 transition-colors",
310
+ children: [
311
+ V ? /* @__PURE__ */ m("span", { className: "h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent" }) : null,
312
+ w("devportal.setup.createAndContinue", "Create & Continue"),
313
+ !V && /* @__PURE__ */ m(d, { size: 16 })
314
+ ]
315
+ })]
316
+ })
317
+ ]
318
+ }),
319
+ E === "app" && /* @__PURE__ */ h("div", {
320
+ className: "rounded-xl border border-border-default bg-surface-raised p-8 shadow-sm",
321
+ children: [
322
+ /* @__PURE__ */ h("div", {
323
+ className: "mb-6 flex items-center gap-3",
324
+ children: [/* @__PURE__ */ m("div", {
325
+ className: "flex h-10 w-10 items-center justify-center rounded-lg bg-primary/10 text-primary",
326
+ children: /* @__PURE__ */ m(c, { size: 20 })
327
+ }), /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("h2", {
328
+ className: "text-lg font-semibold text-foreground",
329
+ children: w("devportal.setup.appTitle", "Create your first app")
330
+ }), /* @__PURE__ */ m("p", {
331
+ className: "text-sm text-muted-foreground",
332
+ children: w("devportal.setup.appSubtitle", "Register the app you want to publish or integrate.")
333
+ })] })]
334
+ }),
335
+ /* @__PURE__ */ h("div", {
336
+ className: "space-y-5",
337
+ children: [
338
+ /* @__PURE__ */ m(r, {
339
+ label: w("devportal.applicationName", "Application Name"),
340
+ value: W,
341
+ onChange: (e) => {
342
+ G(e.target.value), (!K || K === y(W)) && se(y(e.target.value)), Z((e) => ({
343
+ ...e,
344
+ name: void 0
345
+ }));
346
+ },
347
+ placeholder: w("devportal.applicationNamePlaceholder", "My Awesome App"),
348
+ required: !0,
349
+ error: X.name
350
+ }),
351
+ /* @__PURE__ */ h("div", {
352
+ className: "grid grid-cols-2 gap-4",
353
+ children: [/* @__PURE__ */ m(i, {
354
+ label: w("devportal.applicationType", "Application Type"),
355
+ value: q,
356
+ onChange: (e) => {
357
+ ce(e.target.value), Z((e) => ({
358
+ ...e,
359
+ appType: void 0
360
+ }));
361
+ },
362
+ options: _,
363
+ required: !0,
364
+ error: X.appType
365
+ }), /* @__PURE__ */ m(i, {
366
+ label: w("devportal.category", "Category"),
367
+ value: J,
368
+ onChange: (e) => {
369
+ le(e.target.value), Z((e) => ({
370
+ ...e,
371
+ category: void 0
372
+ }));
373
+ },
374
+ options: v,
375
+ required: !0,
376
+ error: X.category
377
+ })]
378
+ }),
379
+ /* @__PURE__ */ m(a, {
380
+ label: w("devportal.shortDescription", "Short Description"),
381
+ value: Y,
382
+ onChange: (e) => {
383
+ ue(e.target.value), Z((e) => ({
384
+ ...e,
385
+ shortDescription: void 0
386
+ }));
387
+ },
388
+ placeholder: w("devportal.shortDescriptionPlaceholder", "A brief description of what your app does"),
389
+ required: !0,
390
+ error: X.shortDescription,
391
+ rows: 2,
392
+ hint: `${Y.length}/200`
393
+ })
394
+ ]
395
+ }),
396
+ /* @__PURE__ */ h("div", {
397
+ className: "mt-8 flex items-center justify-between border-t border-border-default pt-6",
398
+ children: [/* @__PURE__ */ m("button", {
399
+ type: "button",
400
+ onClick: $,
401
+ className: "text-sm text-muted-foreground hover:text-foreground transition-colors",
402
+ children: w("devportal.setup.skipForNow", "Skip for now")
403
+ }), /* @__PURE__ */ h("button", {
404
+ type: "button",
405
+ onClick: () => void pe(),
406
+ disabled: Q,
407
+ className: "inline-flex items-center gap-2 rounded-lg bg-primary px-5 py-2.5 text-sm font-semibold text-primary-foreground hover:bg-primary/90 disabled:opacity-60 transition-colors",
408
+ children: [
409
+ Q ? /* @__PURE__ */ m("span", { className: "h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent" }) : null,
410
+ w("devportal.setup.createApp", "Create App"),
411
+ !Q && /* @__PURE__ */ m(d, { size: 16 })
412
+ ]
413
+ })]
414
+ })
415
+ ]
416
+ }),
417
+ E === "done" && /* @__PURE__ */ h("div", {
418
+ className: "text-center",
419
+ children: [
420
+ /* @__PURE__ */ m("div", {
421
+ className: "mx-auto mb-6 flex h-16 w-16 items-center justify-center rounded-full bg-primary/10 text-primary",
422
+ children: /* @__PURE__ */ m(p, { size: 32 })
423
+ }),
424
+ /* @__PURE__ */ m("h2", {
425
+ className: "text-2xl font-bold text-foreground",
426
+ children: w("devportal.setup.doneTitle", "You're all set!")
427
+ }),
428
+ /* @__PURE__ */ m("p", {
429
+ className: "mt-2 text-muted-foreground",
430
+ children: w("devportal.setup.doneSubtitle", "Your organization and first app are ready. Here's what to do next.")
431
+ }),
432
+ /* @__PURE__ */ h("div", {
433
+ className: "mt-8 grid gap-3 sm:grid-cols-2",
434
+ children: [
435
+ A && /* @__PURE__ */ m(C, {
436
+ icon: /* @__PURE__ */ m(c, { size: 20 }),
437
+ title: w("devportal.setup.viewApp", "View your app"),
438
+ description: w("devportal.setup.viewAppDesc", "Configure OAuth, webhooks, and versioning"),
439
+ onClick: () => T(`/apps/${A}`),
440
+ primary: !0
441
+ }),
442
+ /* @__PURE__ */ m(C, {
443
+ icon: /* @__PURE__ */ m(f, { size: 20 }),
444
+ title: w("devportal.setup.generateApiKey", "Generate API key"),
445
+ description: w("devportal.setup.generateApiKeyDesc", "Create credentials to start calling APIs"),
446
+ onClick: () => T("/api-keys/new")
447
+ }),
448
+ /* @__PURE__ */ m(C, {
449
+ icon: /* @__PURE__ */ m(re, { size: 20 }),
450
+ title: w("devportal.setup.browseDocs", "Browse docs"),
451
+ description: w("devportal.setup.browseDocsDesc", "Learn about publishing, SDKs, and webhooks"),
452
+ onClick: () => T("/docs")
453
+ }),
454
+ O && /* @__PURE__ */ m(C, {
455
+ icon: /* @__PURE__ */ m(l, { size: 20 }),
456
+ title: w("devportal.setup.inviteTeam", "Invite your team"),
457
+ description: w("devportal.setup.inviteTeamDesc", "Add members to collaborate on your apps"),
458
+ onClick: () => T(`/organizations/${O}/members`)
459
+ })
460
+ ]
461
+ }),
462
+ /* @__PURE__ */ h("button", {
463
+ type: "button",
464
+ onClick: () => T("/"),
465
+ className: "mt-8 inline-flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground transition-colors",
466
+ children: [w("devportal.setup.goToDashboard", "Go to dashboard"), /* @__PURE__ */ m(ne, { size: 14 })]
467
+ })
468
+ ]
469
+ })
470
+ ]
471
+ })]
472
+ });
473
+ }, C = ({ icon: e, title: t, description: n, onClick: r, primary: i }) => /* @__PURE__ */ h("button", {
474
+ type: "button",
475
+ onClick: r,
476
+ className: ["flex items-start gap-4 rounded-xl border p-5 text-left transition-colors", i ? "border-primary bg-primary/5 hover:bg-primary/10" : "border-border-default bg-surface-raised hover:bg-surface-hover"].join(" "),
477
+ children: [
478
+ /* @__PURE__ */ m("div", {
479
+ className: ["flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-lg", i ? "bg-primary/20 text-primary" : "bg-muted text-muted-foreground"].join(" "),
480
+ children: e
481
+ }),
482
+ /* @__PURE__ */ h("div", {
483
+ className: "min-w-0 flex-1",
484
+ children: [/* @__PURE__ */ m("p", {
485
+ className: "font-semibold text-foreground",
486
+ children: t
487
+ }), /* @__PURE__ */ m("p", {
488
+ className: "mt-0.5 text-sm text-muted-foreground",
489
+ children: n
490
+ })]
491
+ }),
492
+ /* @__PURE__ */ m(d, {
493
+ size: 16,
494
+ className: "mt-0.5 flex-shrink-0 text-muted-foreground"
495
+ })
496
+ ]
497
+ });
498
+ //#endregion
499
+ export { S as SetupPage };
500
+
501
+ //# sourceMappingURL=SetupPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SetupPage.js","names":[],"sources":["../../../src/devportal/pages/SetupPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useState } from \"react\";\nimport {\n ArrowRight,\n Building2,\n AppWindow,\n Rocket,\n Check,\n Key,\n BookOpen,\n ChevronRight,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n InputField,\n TextareaField,\n SelectField,\n} from \"../components/FormField\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { useDevportalEventBus } from \"../events\";\nimport type { AppType, DeveloperOrgTier } from \"../types\";\nimport { APP_TYPE_LABELS } from \"../utils/constants\";\nimport {\n useCreateOrganizationMutation,\n useCreateApplicationMutation,\n} from \"../../generated/global-operations\";\n\ntype SetupStep = \"org\" | \"app\" | \"done\";\n\nconst TIER_OPTIONS: {\n value: DeveloperOrgTier;\n label: string;\n price: string;\n apps: string;\n calls: string;\n}[] = [\n {\n value: \"FREE\",\n label: \"Free\",\n price: \"Free\",\n apps: \"1 app\",\n calls: \"100K calls/mo\",\n },\n {\n value: \"DEVELOPER\",\n label: \"Developer\",\n price: \"$29/mo\",\n apps: \"3 apps\",\n calls: \"1M calls/mo\",\n },\n {\n value: \"PROFESSIONAL\",\n label: \"Professional\",\n price: \"$99/mo\",\n apps: \"10 apps\",\n calls: \"10M calls/mo\",\n },\n];\n\nconst APP_TYPE_OPTIONS = [\n { value: \"\", label: \"Select type…\" },\n ...Object.entries(APP_TYPE_LABELS).map(([value, label]) => ({\n value,\n label,\n })),\n];\n\nconst CATEGORY_OPTIONS = [\n { value: \"\", label: \"Select category…\" },\n { value: \"productivity\", label: \"Productivity\" },\n { value: \"communication\", label: \"Communication\" },\n { value: \"analytics\", label: \"Analytics\" },\n { value: \"automation\", label: \"Automation\" },\n { value: \"developer-tools\", label: \"Developer Tools\" },\n { value: \"finance\", label: \"Finance\" },\n { value: \"hr\", label: \"HR & People\" },\n { value: \"marketing\", label: \"Marketing\" },\n { value: \"project-management\", label: \"Project Management\" },\n { value: \"security\", label: \"Security\" },\n { value: \"support\", label: \"Support\" },\n { value: \"other\", label: \"Other\" },\n];\n\nfunction generateSlug(name: string): string {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n}\n\n/** Mark that the user has interacted with setup so the dashboard gate won't redirect again. */\nfunction markSetupSeen() {\n try {\n localStorage.setItem(\"devportal_setup_dismissed\", \"1\");\n } catch {\n // localStorage unavailable — not critical\n }\n}\n\n// ─── Step indicator ────────────────────────────────────────────────────────\n\nconst STEPS: { key: SetupStep; label: string }[] = [\n { key: \"org\", label: \"Organization\" },\n { key: \"app\", label: \"First app\" },\n { key: \"done\", label: \"Done\" },\n];\n\nconst StepIndicator: FC<{ current: SetupStep }> = ({ current }) => {\n const currentIdx = STEPS.findIndex((s) => s.key === current);\n return (\n <div className=\"flex items-center gap-0\">\n {STEPS.map((step, idx) => {\n const isCompleted = idx < currentIdx;\n const isActive = idx === currentIdx;\n return (\n <div key={step.key} className=\"flex items-center\">\n <div className=\"flex flex-col items-center gap-1.5\">\n <div\n className={[\n \"flex h-8 w-8 items-center justify-center rounded-full text-sm font-semibold transition-colors\",\n isCompleted\n ? \"bg-primary text-primary-foreground\"\n : isActive\n ? \"bg-primary text-primary-foreground ring-4 ring-primary/20\"\n : \"bg-muted text-muted-foreground\",\n ].join(\" \")}\n >\n {isCompleted ? <Check size={14} /> : idx + 1}\n </div>\n <span\n className={[\n \"text-xs font-medium whitespace-nowrap\",\n isActive ? \"text-foreground\" : \"text-muted-foreground\",\n ].join(\" \")}\n >\n {step.label}\n </span>\n </div>\n {idx < STEPS.length - 1 && (\n <div\n className={[\n \"mx-3 mb-5 h-px w-16 flex-shrink-0 transition-colors\",\n idx < currentIdx ? \"bg-primary\" : \"bg-border\",\n ].join(\" \")}\n />\n )}\n </div>\n );\n })}\n </div>\n );\n};\n\n// ─── Main component ────────────────────────────────────────────────────────\n\nexport const SetupPage: FC = () => {\n const { navigate, basePath } = useDevportal();\n const { t } = useI18n();\n const bus = useDevportalEventBus();\n const tr = (key: string, fallback: string): string => {\n const v = t(key);\n return v === key ? fallback : v;\n };\n\n const handleNavigate = (path: string) => navigate?.(`${basePath}${path}`);\n\n const [step, setStep] = useState<SetupStep>(\"org\");\n\n // IDs created during wizard — carried forward for success CTAs\n const [createdOrgId, setCreatedOrgId] = useState<string | null>(null);\n const [createdAppId, setCreatedAppId] = useState<string | null>(null);\n\n // ── Step 1: org ──────────────────────────────────────────────\n const [orgName, setOrgName] = useState(\"\");\n const [orgSlug, setOrgSlug] = useState(\"\");\n const [orgDescription, setOrgDescription] = useState(\"\");\n const [orgTier, setOrgTier] = useState<DeveloperOrgTier>(\"FREE\");\n const [orgErrors, setOrgErrors] = useState<{ name?: string; slug?: string }>(\n {},\n );\n\n const [createOrg, { loading: creatingOrg }] = useCreateOrganizationMutation();\n\n const validateOrg = () => {\n const errs: { name?: string; slug?: string } = {};\n if (!orgName.trim())\n errs.name = tr(\n \"devportal.orgNameRequired\",\n \"Organization name is required\",\n );\n else if (orgName.length < 2)\n errs.name = tr(\n \"devportal.orgNameTooShort\",\n \"Name must be at least 2 characters\",\n );\n if (!orgSlug.trim())\n errs.slug = tr(\"devportal.slugRequired\", \"Slug is required\");\n else if (!/^[a-z0-9-]+$/.test(orgSlug))\n errs.slug = tr(\n \"devportal.slugInvalid\",\n \"Lowercase letters, numbers, and hyphens only\",\n );\n setOrgErrors(errs);\n return Object.keys(errs).length === 0;\n };\n\n const handleOrgSubmit = async () => {\n if (!validateOrg()) return;\n try {\n const result = await createOrg({\n variables: {\n input: {\n name: orgName,\n slug: orgSlug || undefined,\n description: orgDescription || undefined,\n metadata: orgTier !== \"FREE\" ? { tier: orgTier } : undefined,\n },\n },\n });\n const id = result.data?.createDeveloperOrganization?.id;\n if (id) {\n bus.emit(\"devportal.org.created\", {\n organizationId: id,\n name: orgName,\n });\n setCreatedOrgId(id);\n setStep(\"app\");\n }\n } catch {\n // error surfaced via Apollo cache; leave the form open\n }\n };\n\n // ── Step 2: app ──────────────────────────────────────────────\n const [appName, setAppName] = useState(\"\");\n const [appSlug, setAppSlug] = useState(\"\");\n const [appType, setAppType] = useState<AppType | \"\">(\"\");\n const [appCategory, setAppCategory] = useState(\"\");\n const [appShortDesc, setAppShortDesc] = useState(\"\");\n const [appErrors, setAppErrors] = useState<{\n name?: string;\n appType?: string;\n category?: string;\n shortDescription?: string;\n }>({});\n\n const [createApp, { loading: creatingApp }] = useCreateApplicationMutation();\n\n const validateApp = () => {\n const errs: typeof appErrors = {};\n if (!appName.trim())\n errs.name = tr(\n \"devportal.appNameRequired\",\n \"Application name is required\",\n );\n else if (appName.length < 3)\n errs.name = tr(\n \"devportal.nameTooShort\",\n \"Name must be at least 3 characters\",\n );\n if (!appType)\n errs.appType = tr(\n \"devportal.appTypeRequired\",\n \"Application type is required\",\n );\n if (!appCategory)\n errs.category = tr(\"devportal.categoryRequired\", \"Category is required\");\n if (!appShortDesc.trim())\n errs.shortDescription = tr(\n \"devportal.shortDescriptionRequired\",\n \"Short description is required\",\n );\n setAppErrors(errs);\n return Object.keys(errs).length === 0;\n };\n\n const handleAppSubmit = async () => {\n if (!validateApp()) return;\n try {\n const result = await createApp({\n variables: {\n input: {\n name: appName,\n slug: appSlug || undefined,\n appType: appType as AppType,\n category: appCategory || undefined,\n shortDescription: appShortDesc || undefined,\n visibility: \"PRIVATE\",\n developerOrganizationId: createdOrgId || undefined,\n },\n },\n });\n const id = result.data?.createApplication?.id;\n if (id) {\n bus.emit(\"devportal.app.created\", {\n appId: id,\n name: appName,\n appType,\n organizationId: createdOrgId,\n });\n setCreatedAppId(id);\n markSetupSeen();\n setStep(\"done\");\n }\n } catch {\n // error surfaced via Apollo cache\n }\n };\n\n const handleSkip = () => {\n markSetupSeen();\n handleNavigate(\"/\");\n };\n\n // ─── Render ─────────────────────────────────────────────────\n\n return (\n <main className=\"min-h-screen bg-surface-default\">\n {/* Header */}\n <div className=\"border-b border-border-default bg-surface-raised\">\n <div className=\"mx-auto max-w-2xl px-6 py-5\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-9 w-9 items-center justify-center rounded-lg bg-primary/10 text-primary\">\n <Rocket size={20} />\n </div>\n <div>\n <p className=\"text-xs font-medium text-muted-foreground\">\n {tr(\"devportal.developerPortal\", \"Developer Portal\")}\n </p>\n <h1 className=\"text-base font-semibold text-foreground\">\n {tr(\"devportal.setup.title\", \"Get set up\")}\n </h1>\n </div>\n </div>\n {step !== \"done\" && (\n <button\n type=\"button\"\n onClick={handleSkip}\n className=\"text-sm text-muted-foreground hover:text-foreground transition-colors\"\n >\n {tr(\"devportal.setup.skipForNow\", \"Skip for now\")}\n </button>\n )}\n </div>\n </div>\n </div>\n\n {/* Content */}\n <div className=\"mx-auto max-w-2xl px-6 py-10\">\n {/* Step indicator */}\n <div className=\"mb-10 flex justify-center\">\n <StepIndicator current={step} />\n </div>\n\n {/* ── Step 1: Organization ─────────────────────── */}\n {step === \"org\" && (\n <div className=\"rounded-xl border border-border-default bg-surface-raised p-8 shadow-sm\">\n <div className=\"mb-6 flex items-center gap-3\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-lg bg-primary/10 text-primary\">\n <Building2 size={20} />\n </div>\n <div>\n <h2 className=\"text-lg font-semibold text-foreground\">\n {tr(\"devportal.setup.orgTitle\", \"Set up your organization\")}\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n {tr(\n \"devportal.setup.orgSubtitle\",\n \"This groups your apps and teams under one publisher identity.\",\n )}\n </p>\n </div>\n </div>\n\n <div className=\"space-y-5\">\n <InputField\n label={tr(\"devportal.organizationName\", \"Organization Name\")}\n value={orgName}\n onChange={(e) => {\n setOrgName(e.target.value);\n if (!orgSlug || orgSlug === generateSlug(orgName)) {\n setOrgSlug(generateSlug(e.target.value));\n }\n setOrgErrors((p) => ({ ...p, name: undefined }));\n }}\n placeholder={tr(\n \"devportal.organizationNamePlaceholder\",\n \"Acme Development\",\n )}\n required\n error={orgErrors.name}\n />\n\n <InputField\n label={tr(\"devportal.slug\", \"Slug\")}\n value={orgSlug}\n onChange={(e) => {\n setOrgSlug(e.target.value.toLowerCase());\n setOrgErrors((p) => ({ ...p, slug: undefined }));\n }}\n placeholder=\"acme-dev\"\n required\n error={orgErrors.slug}\n hint={tr(\n \"devportal.slugHint\",\n \"URL-friendly identifier — auto-generated from name\",\n )}\n />\n\n <TextareaField\n label={tr(\"devportal.description\", \"Description\")}\n value={orgDescription}\n onChange={(e) => setOrgDescription(e.target.value)}\n placeholder={tr(\n \"devportal.orgDescriptionPlaceholder\",\n \"Tell us about your organization…\",\n )}\n rows={2}\n />\n\n {/* Tier cards */}\n <div>\n <p className=\"mb-2 text-sm font-medium text-foreground\">\n {tr(\"devportal.selectPlan\", \"Select Plan\")}\n </p>\n <div className=\"grid grid-cols-3 gap-3\">\n {TIER_OPTIONS.map((tier) => {\n const active = orgTier === tier.value;\n return (\n <button\n key={tier.value}\n type=\"button\"\n onClick={() => setOrgTier(tier.value)}\n className={[\n \"rounded-lg border p-3 text-left text-sm transition-colors\",\n active\n ? \"border-primary bg-primary/5 ring-2 ring-primary\"\n : \"border-border-default hover:border-muted-foreground/50\",\n ].join(\" \")}\n >\n <p className=\"font-semibold text-foreground\">\n {tier.label}\n </p>\n <p className=\"mt-0.5 text-xs text-primary\">\n {tier.price}\n </p>\n <p className=\"mt-1.5 text-xs text-muted-foreground\">\n {tier.apps}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {tier.calls}\n </p>\n </button>\n );\n })}\n </div>\n </div>\n </div>\n\n <div className=\"mt-8 flex items-center justify-between border-t border-border-default pt-6\">\n <button\n type=\"button\"\n onClick={handleSkip}\n className=\"text-sm text-muted-foreground hover:text-foreground transition-colors\"\n >\n {tr(\"devportal.setup.skipForNow\", \"Skip for now\")}\n </button>\n <button\n type=\"button\"\n onClick={() => void handleOrgSubmit()}\n disabled={creatingOrg}\n className=\"inline-flex items-center gap-2 rounded-lg bg-primary px-5 py-2.5 text-sm font-semibold text-primary-foreground hover:bg-primary/90 disabled:opacity-60 transition-colors\"\n >\n {creatingOrg ? (\n <span className=\"h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent\" />\n ) : null}\n {tr(\"devportal.setup.createAndContinue\", \"Create & Continue\")}\n {!creatingOrg && <ChevronRight size={16} />}\n </button>\n </div>\n </div>\n )}\n\n {/* ── Step 2: First app ─────────────────────── */}\n {step === \"app\" && (\n <div className=\"rounded-xl border border-border-default bg-surface-raised p-8 shadow-sm\">\n <div className=\"mb-6 flex items-center gap-3\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-lg bg-primary/10 text-primary\">\n <AppWindow size={20} />\n </div>\n <div>\n <h2 className=\"text-lg font-semibold text-foreground\">\n {tr(\"devportal.setup.appTitle\", \"Create your first app\")}\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n {tr(\n \"devportal.setup.appSubtitle\",\n \"Register the app you want to publish or integrate.\",\n )}\n </p>\n </div>\n </div>\n\n <div className=\"space-y-5\">\n <InputField\n label={tr(\"devportal.applicationName\", \"Application Name\")}\n value={appName}\n onChange={(e) => {\n setAppName(e.target.value);\n if (!appSlug || appSlug === generateSlug(appName)) {\n setAppSlug(generateSlug(e.target.value));\n }\n setAppErrors((p) => ({ ...p, name: undefined }));\n }}\n placeholder={tr(\n \"devportal.applicationNamePlaceholder\",\n \"My Awesome App\",\n )}\n required\n error={appErrors.name}\n />\n\n <div className=\"grid grid-cols-2 gap-4\">\n <SelectField\n label={tr(\"devportal.applicationType\", \"Application Type\")}\n value={appType}\n onChange={(e) => {\n setAppType(e.target.value as AppType);\n setAppErrors((p) => ({ ...p, appType: undefined }));\n }}\n options={APP_TYPE_OPTIONS}\n required\n error={appErrors.appType}\n />\n <SelectField\n label={tr(\"devportal.category\", \"Category\")}\n value={appCategory}\n onChange={(e) => {\n setAppCategory(e.target.value);\n setAppErrors((p) => ({ ...p, category: undefined }));\n }}\n options={CATEGORY_OPTIONS}\n required\n error={appErrors.category}\n />\n </div>\n\n <TextareaField\n label={tr(\"devportal.shortDescription\", \"Short Description\")}\n value={appShortDesc}\n onChange={(e) => {\n setAppShortDesc(e.target.value);\n setAppErrors((p) => ({ ...p, shortDescription: undefined }));\n }}\n placeholder={tr(\n \"devportal.shortDescriptionPlaceholder\",\n \"A brief description of what your app does\",\n )}\n required\n error={appErrors.shortDescription}\n rows={2}\n hint={`${appShortDesc.length}/200`}\n />\n </div>\n\n <div className=\"mt-8 flex items-center justify-between border-t border-border-default pt-6\">\n <button\n type=\"button\"\n onClick={handleSkip}\n className=\"text-sm text-muted-foreground hover:text-foreground transition-colors\"\n >\n {tr(\"devportal.setup.skipForNow\", \"Skip for now\")}\n </button>\n <button\n type=\"button\"\n onClick={() => void handleAppSubmit()}\n disabled={creatingApp}\n className=\"inline-flex items-center gap-2 rounded-lg bg-primary px-5 py-2.5 text-sm font-semibold text-primary-foreground hover:bg-primary/90 disabled:opacity-60 transition-colors\"\n >\n {creatingApp ? (\n <span className=\"h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent\" />\n ) : null}\n {tr(\"devportal.setup.createApp\", \"Create App\")}\n {!creatingApp && <ChevronRight size={16} />}\n </button>\n </div>\n </div>\n )}\n\n {/* ── Step 3: Done ─────────────────────────── */}\n {step === \"done\" && (\n <div className=\"text-center\">\n <div className=\"mx-auto mb-6 flex h-16 w-16 items-center justify-center rounded-full bg-primary/10 text-primary\">\n <Rocket size={32} />\n </div>\n <h2 className=\"text-2xl font-bold text-foreground\">\n {tr(\"devportal.setup.doneTitle\", \"You're all set!\")}\n </h2>\n <p className=\"mt-2 text-muted-foreground\">\n {tr(\n \"devportal.setup.doneSubtitle\",\n \"Your organization and first app are ready. Here's what to do next.\",\n )}\n </p>\n\n <div className=\"mt-8 grid gap-3 sm:grid-cols-2\">\n {createdAppId && (\n <NextStepCard\n icon={<AppWindow size={20} />}\n title={tr(\"devportal.setup.viewApp\", \"View your app\")}\n description={tr(\n \"devportal.setup.viewAppDesc\",\n \"Configure OAuth, webhooks, and versioning\",\n )}\n onClick={() => handleNavigate(`/apps/${createdAppId}`)}\n primary\n />\n )}\n <NextStepCard\n icon={<Key size={20} />}\n title={tr(\"devportal.setup.generateApiKey\", \"Generate API key\")}\n description={tr(\n \"devportal.setup.generateApiKeyDesc\",\n \"Create credentials to start calling APIs\",\n )}\n onClick={() => handleNavigate(\"/api-keys/new\")}\n />\n <NextStepCard\n icon={<BookOpen size={20} />}\n title={tr(\"devportal.setup.browseDocs\", \"Browse docs\")}\n description={tr(\n \"devportal.setup.browseDocsDesc\",\n \"Learn about publishing, SDKs, and webhooks\",\n )}\n onClick={() => handleNavigate(\"/docs\")}\n />\n {createdOrgId && (\n <NextStepCard\n icon={<Building2 size={20} />}\n title={tr(\"devportal.setup.inviteTeam\", \"Invite your team\")}\n description={tr(\n \"devportal.setup.inviteTeamDesc\",\n \"Add members to collaborate on your apps\",\n )}\n onClick={() =>\n handleNavigate(`/organizations/${createdOrgId}/members`)\n }\n />\n )}\n </div>\n\n <button\n type=\"button\"\n onClick={() => handleNavigate(\"/\")}\n className=\"mt-8 inline-flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground transition-colors\"\n >\n {tr(\"devportal.setup.goToDashboard\", \"Go to dashboard\")}\n <ArrowRight size={14} />\n </button>\n </div>\n )}\n </div>\n </main>\n );\n};\n\n// ─── Next-step card ────────────────────────────────────────────────────────\n\nconst NextStepCard: FC<{\n icon: React.ReactNode;\n title: string;\n description: string;\n onClick: () => void;\n primary?: boolean;\n}> = ({ icon, title, description, onClick, primary }) => (\n <button\n type=\"button\"\n onClick={onClick}\n className={[\n \"flex items-start gap-4 rounded-xl border p-5 text-left transition-colors\",\n primary\n ? \"border-primary bg-primary/5 hover:bg-primary/10\"\n : \"border-border-default bg-surface-raised hover:bg-surface-hover\",\n ].join(\" \")}\n >\n <div\n className={[\n \"flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-lg\",\n primary\n ? \"bg-primary/20 text-primary\"\n : \"bg-muted text-muted-foreground\",\n ].join(\" \")}\n >\n {icon}\n </div>\n <div className=\"min-w-0 flex-1\">\n <p className=\"font-semibold text-foreground\">{title}</p>\n <p className=\"mt-0.5 text-sm text-muted-foreground\">{description}</p>\n </div>\n <ChevronRight\n size={16}\n className=\"mt-0.5 flex-shrink-0 text-muted-foreground\"\n />\n </button>\n);\n"],"mappings":"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"}