@burdenoff/microfe-devportal 2026.915.2 → 2026.915.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/devportal/hooks/index.d.ts +1 -1
- package/dist/devportal/hooks/index.d.ts.map +1 -1
- package/dist/devportal/hooks/useCarrierPickupLocations.d.ts +8 -1
- package/dist/devportal/hooks/useCarrierPickupLocations.d.ts.map +1 -1
- package/dist/devportal/hooks/useCarrierPickupLocations.js +6 -3
- package/dist/devportal/hooks/useCarrierPickupLocations.js.map +1 -1
- package/dist/devportal/pages/CreateOrganizationPage.d.ts.map +1 -1
- package/dist/devportal/pages/CreateOrganizationPage.js +63 -63
- package/dist/devportal/pages/CreateOrganizationPage.js.map +1 -1
- package/dist/devportal/pages/OrganizationDetailPage.d.ts.map +1 -1
- package/dist/devportal/pages/OrganizationDetailPage.js +234 -234
- package/dist/devportal/pages/OrganizationDetailPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -6,6 +6,6 @@
|
|
|
6
6
|
export { apolloClient, parseGraphQLError, getErrorMessage, isAuthError, isValidationError, clearApolloCache, resetApolloStore, type GraphQLErrorInfo, } from './useGraphQL';
|
|
7
7
|
export { DevPortalProvider } from './DevPortalProvider';
|
|
8
8
|
export { useDevportalPermission } from './usePermission';
|
|
9
|
-
export { useCarrierPickupLocations, type CarrierPickupLocation, type UseCarrierPickupLocationsResult, } from './useCarrierPickupLocations';
|
|
9
|
+
export { useCarrierPickupLocations, capitalizeCarrierName, type CarrierPickupLocation, type UseCarrierPickupLocationsResult, } from './useCarrierPickupLocations';
|
|
10
10
|
export * from '../../generated/global-operations';
|
|
11
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/devportal/hooks/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,KAAK,gBAAgB,GACtB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/devportal/hooks/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,KAAK,gBAAgB,GACtB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAIzD,OAAO,EACL,yBAAyB,EACzB,qBAAqB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,+BAA+B,GACrC,MAAM,6BAA6B,CAAC;AAGrC,cAAc,mCAAmC,CAAC"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* One of
|
|
2
|
+
* One of a shipping carrier's own registered pickup/warehouse addresses.
|
|
3
|
+
* Not organization-scoped — a pickup location belongs to whichever carrier
|
|
4
|
+
* account it's registered with (Shiprocket today; more carriers may be
|
|
5
|
+
* added later, each contributing their own locations).
|
|
3
6
|
*
|
|
4
7
|
* Backs the "Pickup Pincode" selector on the org creation form and the
|
|
5
8
|
* Fulfillment settings tab — sellers pick one of these instead of typing an
|
|
@@ -9,7 +12,11 @@
|
|
|
9
12
|
export interface CarrierPickupLocation {
|
|
10
13
|
label: string;
|
|
11
14
|
postalCode: string;
|
|
15
|
+
/** Which carrier this address is registered with, e.g. "shiprocket". */
|
|
16
|
+
carrier: string;
|
|
12
17
|
}
|
|
18
|
+
/** "shiprocket" -> "Shiprocket" — for display in the pickup-location dropdown. */
|
|
19
|
+
export declare function capitalizeCarrierName(carrier: string): string;
|
|
13
20
|
export interface UseCarrierPickupLocationsResult {
|
|
14
21
|
/** Registered pickup locations, or [] when Shiprocket isn't configured, the
|
|
15
22
|
* lookup fails, or the actor isn't authenticated yet — callers should fall
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCarrierPickupLocations.d.ts","sourceRoot":"","sources":["../../../src/devportal/hooks/useCarrierPickupLocations.ts"],"names":[],"mappings":"AAGA
|
|
1
|
+
{"version":3,"file":"useCarrierPickupLocations.d.ts","sourceRoot":"","sources":["../../../src/devportal/hooks/useCarrierPickupLocations.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;CACjB;AAYD,kFAAkF;AAClF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAI7D;AAED,MAAM,WAAW,+BAA+B;IAC9C;;4EAEwE;IACxE,SAAS,EAAE,qBAAqB,EAAE,CAAC;IACnC,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,yBAAyB,IAAI,+BAA+B,CA4B3E"}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { useEffect as e, useState as t } from "react";
|
|
2
2
|
import { graphqlFetch as n } from "@burdenoff/fe-libs/shared/graphql";
|
|
3
3
|
//#region src/devportal/hooks/useCarrierPickupLocations.ts
|
|
4
|
-
var r = "\n query DevportalCarrierPickupLocations {\n carrierPickupLocations {\n label\n postalCode\n }\n }\n";
|
|
5
|
-
function i() {
|
|
4
|
+
var r = "\n query DevportalCarrierPickupLocations {\n carrierPickupLocations {\n label\n postalCode\n carrier\n }\n }\n";
|
|
5
|
+
function i(e) {
|
|
6
|
+
return e.length > 0 ? e[0].toUpperCase() + e.slice(1) : e;
|
|
7
|
+
}
|
|
8
|
+
function a() {
|
|
6
9
|
let [i, a] = t([]), [o, s] = t(!0);
|
|
7
10
|
return e(() => {
|
|
8
11
|
let e = !1;
|
|
@@ -24,6 +27,6 @@ function i() {
|
|
|
24
27
|
};
|
|
25
28
|
}
|
|
26
29
|
//#endregion
|
|
27
|
-
export { i as useCarrierPickupLocations };
|
|
30
|
+
export { i as capitalizeCarrierName, a as useCarrierPickupLocations };
|
|
28
31
|
|
|
29
32
|
//# sourceMappingURL=useCarrierPickupLocations.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCarrierPickupLocations.js","names":[],"sources":["../../../src/devportal/hooks/useCarrierPickupLocations.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\nimport { graphqlFetch } from \"@burdenoff/fe-libs/shared/graphql\";\n\n/**\n * One of
|
|
1
|
+
{"version":3,"file":"useCarrierPickupLocations.js","names":[],"sources":["../../../src/devportal/hooks/useCarrierPickupLocations.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\nimport { graphqlFetch } from \"@burdenoff/fe-libs/shared/graphql\";\n\n/**\n * One of a shipping carrier's own registered pickup/warehouse addresses.\n * Not organization-scoped — a pickup location belongs to whichever carrier\n * account it's registered with (Shiprocket today; more carriers may be\n * added later, each contributing their own locations).\n *\n * Backs the \"Pickup Pincode\" selector on the org creation form and the\n * Fulfillment settings tab — sellers pick one of these instead of typing an\n * arbitrary pincode that checkout would later refuse to ship (see\n * global-store-svc's CarrierPickupUnavailableError / BOFF-7192).\n */\nexport interface CarrierPickupLocation {\n label: string;\n postalCode: string;\n /** Which carrier this address is registered with, e.g. \"shiprocket\". */\n carrier: string;\n}\n\nconst CARRIER_PICKUP_LOCATIONS_QUERY = `\n query DevportalCarrierPickupLocations {\n carrierPickupLocations {\n label\n postalCode\n carrier\n }\n }\n`;\n\n/** \"shiprocket\" -> \"Shiprocket\" — for display in the pickup-location dropdown. */\nexport function capitalizeCarrierName(carrier: string): string {\n return carrier.length > 0\n ? carrier[0].toUpperCase() + carrier.slice(1)\n : carrier;\n}\n\nexport interface UseCarrierPickupLocationsResult {\n /** Registered pickup locations, or [] when Shiprocket isn't configured, the\n * lookup fails, or the actor isn't authenticated yet — callers should fall\n * back to a free-text pincode field in that case, never block on it. */\n locations: CarrierPickupLocation[];\n loading: boolean;\n}\n\nexport function useCarrierPickupLocations(): UseCarrierPickupLocationsResult {\n const [locations, setLocations] = useState<CarrierPickupLocation[]>([]);\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n let cancelled = false;\n\n graphqlFetch<{ carrierPickupLocations: CarrierPickupLocation[] }>({\n gateway: \"global\",\n query: CARRIER_PICKUP_LOCATIONS_QUERY,\n })\n .then((result) => {\n if (cancelled) return;\n setLocations(result.data?.carrierPickupLocations ?? []);\n })\n .catch(() => {\n if (!cancelled) setLocations([]);\n })\n .finally(() => {\n if (!cancelled) setLoading(false);\n });\n\n return () => {\n cancelled = true;\n };\n }, []);\n\n return { locations, loading };\n}\n"],"mappings":";;;AAqBA,IAAM,IAAiC;AAWvC,SAAgB,EAAsB,GAAyB;AAC7D,QAAO,EAAQ,SAAS,IACpB,EAAQ,GAAG,aAAa,GAAG,EAAQ,MAAM,EAAE,GAC3C;;AAWN,SAAgB,IAA6D;CAC3E,IAAM,CAAC,GAAW,KAAgB,EAAkC,EAAE,CAAC,EACjE,CAAC,GAAS,KAAc,EAAS,GAAK;AAyB5C,QAvBA,QAAgB;EACd,IAAI,IAAY;AAiBhB,SAfA,EAAkE;GAChE,SAAS;GACT,OAAO;GACR,CAAC,CACC,MAAM,MAAW;AACZ,QACJ,EAAa,EAAO,MAAM,0BAA0B,EAAE,CAAC;IACvD,CACD,YAAY;AACX,GAAK,KAAW,EAAa,EAAE,CAAC;IAChC,CACD,cAAc;AACb,GAAK,KAAW,EAAW,GAAM;IACjC,QAES;AACX,OAAY;;IAEb,EAAE,CAAC,EAEC;EAAE;EAAW;EAAS"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateOrganizationPage.d.ts","sourceRoot":"","sources":["../../../src/devportal/pages/CreateOrganizationPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"CreateOrganizationPage.d.ts","sourceRoot":"","sources":["../../../src/devportal/pages/CreateOrganizationPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAuDhC;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,EAAE,EAqmBpC,CAAC"}
|
|
@@ -3,21 +3,21 @@ import { useTr as t } from "../utils/i18n.js";
|
|
|
3
3
|
import { cn as n } from "../utils/cn.js";
|
|
4
4
|
import { useDevportalEventBus as r } from "../events/index.js";
|
|
5
5
|
import { orgSectionPath as i, useIsSellerSection as a } from "../hooks/useIsSellerSection.js";
|
|
6
|
-
import { useCreateBillingAccountMutation as
|
|
7
|
-
import { PageLayout as
|
|
8
|
-
import { InputField as
|
|
9
|
-
import { PermissionGuard as
|
|
6
|
+
import { useCreateBillingAccountMutation as ee, useCreateOrganizationMutation as te, useCreateSellerOrganizationMutation as o, useGetBillingAccountsByOrgQuery as s, useLinkDevOrgBillingAccountMutation as c } from "../../generated/global-operations.js";
|
|
7
|
+
import { PageLayout as l, PageSection as u } from "../components/PageLayout.js";
|
|
8
|
+
import { InputField as d, SelectField as f, TextareaField as p } from "../components/FormField.js";
|
|
9
|
+
import { PermissionGuard as m } from "../components/PermissionGuard.js";
|
|
10
10
|
import "../components/index.js";
|
|
11
|
-
import { useCarrierPickupLocations as g } from "../hooks/useCarrierPickupLocations.js";
|
|
11
|
+
import { capitalizeCarrierName as h, useCarrierPickupLocations as g } from "../hooks/useCarrierPickupLocations.js";
|
|
12
12
|
import "../hooks/index.js";
|
|
13
13
|
import { useEffect as _, useMemo as v, useState as y } from "react";
|
|
14
|
-
import { Building2 as
|
|
15
|
-
import { Fragment as
|
|
14
|
+
import { Building2 as ne, Check as b, Link2 as re, Loader2 as x, X as S } from "lucide-react";
|
|
15
|
+
import { Fragment as C, jsx as w, jsxs as T } from "react/jsx-runtime";
|
|
16
16
|
//#region src/devportal/pages/CreateOrganizationPage.tsx
|
|
17
|
-
var
|
|
18
|
-
let { navigate:
|
|
17
|
+
var E = () => {
|
|
18
|
+
let { navigate: E, basePath: D, currentUser: O, tenantId: ie, setActiveOrgId: ae, setActivePhysicalOrgId: k } = e(), A = a(), j = t(), [M, N] = y({}), [P] = te(), [F] = o(), [I] = ee(), [L] = c(), R = r(), [z, B] = y("idle"), V = z !== "idle", [H, U] = y("auto"), [W, G] = y(null), { data: K, loading: q } = s({
|
|
19
19
|
fetchPolicy: "cache-and-network",
|
|
20
|
-
context: { headers: { "x-org-id":
|
|
20
|
+
context: { headers: { "x-org-id": ie ?? "" } }
|
|
21
21
|
}), J = v(() => K?.getBillingAccountsByOrg ?? [], [K]);
|
|
22
22
|
_(() => {
|
|
23
23
|
if (!(H !== "existing" || q)) {
|
|
@@ -42,13 +42,13 @@ var O = () => {
|
|
|
42
42
|
supportEmail: "",
|
|
43
43
|
pickupPostalCode: ""
|
|
44
44
|
}), { locations: Z } = g(), Q = (e) => {
|
|
45
|
-
|
|
46
|
-
},
|
|
45
|
+
E?.(`${D}${e}`);
|
|
46
|
+
}, oe = (e) => e.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, ""), se = (e) => {
|
|
47
47
|
let t = e.target.value;
|
|
48
48
|
X((e) => ({
|
|
49
49
|
...e,
|
|
50
50
|
name: t,
|
|
51
|
-
slug: e.slug ||
|
|
51
|
+
slug: e.slug || oe(t)
|
|
52
52
|
})), M.name && N((e) => ({
|
|
53
53
|
...e,
|
|
54
54
|
name: void 0
|
|
@@ -61,21 +61,21 @@ var O = () => {
|
|
|
61
61
|
...t,
|
|
62
62
|
[e]: void 0
|
|
63
63
|
}));
|
|
64
|
-
},
|
|
64
|
+
}, ce = () => {
|
|
65
65
|
let e = {};
|
|
66
66
|
return Y.name.trim() ? Y.name.length < 2 ? e.name = j("devportal.orgNameTooShort", "Name must be at least 2 characters") : Y.name.length > 100 && (e.name = j("devportal.nameTooLong", "Name must be less than 100 characters")) : e.name = j("devportal.orgNameRequired", "Organization name is required"), Y.slug.trim() ? /^[a-z0-9-]+$/.test(Y.slug) || (e.slug = j("devportal.slugInvalid", "Slug can only contain lowercase letters, numbers, and hyphens")) : e.slug = j("devportal.slugRequired", "Slug is required"), Y.contactEmail && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(Y.contactEmail) && (e.contactEmail = j("devportal.invalidEmailAddress", "Invalid email address")), Y.supportEmail && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(Y.supportEmail) && (e.supportEmail = j("devportal.invalidEmailAddress", "Invalid email address")), N(e), Object.keys(e).length === 0;
|
|
67
67
|
};
|
|
68
|
-
return /* @__PURE__ */
|
|
68
|
+
return /* @__PURE__ */ w(m, {
|
|
69
69
|
authOnly: !0,
|
|
70
|
-
children: /* @__PURE__ */
|
|
70
|
+
children: /* @__PURE__ */ w(l, {
|
|
71
71
|
title: j("devportal.createOrganization", "Create Organization"),
|
|
72
72
|
description: A ? j("devportal.createSellerOrganizationDescription", "Set up a seller organization to start selling physical products") : j("devportal.createOrganizationDescription", "Set up a developer organization to collaborate with your team"),
|
|
73
73
|
purpose: A ? j("devportal.createSellerOrganizationPurpose", "A seller organization is the shared owner of your physical listings, orders, and revenue. Create one here — you can invite members and complete legal/tax details afterwards.") : j("devportal.createOrganizationPurpose", "An organization is the shared owner of your apps, members, and revenue. Create one here so your team works under a single identity — pick a name and tier now; you can invite members and verify it afterwards."),
|
|
74
|
-
backLink: `${
|
|
74
|
+
backLink: `${D}${i(A)}`,
|
|
75
75
|
backLabel: j("devportal.backToOrganizations", "Back to Organizations"),
|
|
76
|
-
children: /* @__PURE__ */
|
|
76
|
+
children: /* @__PURE__ */ T("form", {
|
|
77
77
|
onSubmit: async (e) => {
|
|
78
|
-
if (e.preventDefault(),
|
|
78
|
+
if (e.preventDefault(), ce()) {
|
|
79
79
|
B("creating-org");
|
|
80
80
|
try {
|
|
81
81
|
let e = {
|
|
@@ -94,7 +94,7 @@ var O = () => {
|
|
|
94
94
|
if (R.emit("devportal.org.created", {
|
|
95
95
|
organizationId: t,
|
|
96
96
|
name: Y.name
|
|
97
|
-
}), A ?
|
|
97
|
+
}), A ? k(t) : ae(t), H === "existing" && W) {
|
|
98
98
|
B("linking-billing");
|
|
99
99
|
try {
|
|
100
100
|
await L({ variables: {
|
|
@@ -107,7 +107,7 @@ var O = () => {
|
|
|
107
107
|
try {
|
|
108
108
|
let e = (await I({ variables: { input: {
|
|
109
109
|
name: Y.name,
|
|
110
|
-
email:
|
|
110
|
+
email: O?.email ?? ""
|
|
111
111
|
} } })).data?.createBillingAccount?.id;
|
|
112
112
|
e && await L({ variables: {
|
|
113
113
|
organizationId: t,
|
|
@@ -123,22 +123,22 @@ var O = () => {
|
|
|
123
123
|
},
|
|
124
124
|
className: "space-y-8 max-w-3xl",
|
|
125
125
|
children: [
|
|
126
|
-
/* @__PURE__ */
|
|
126
|
+
/* @__PURE__ */ w(u, {
|
|
127
127
|
title: j("devportal.organizationDetails", "Organization Details"),
|
|
128
128
|
description: j("devportal.organizationDetailsDescription", "Basic information about your organization"),
|
|
129
|
-
children: /* @__PURE__ */
|
|
129
|
+
children: /* @__PURE__ */ T("div", {
|
|
130
130
|
className: "space-y-4",
|
|
131
131
|
children: [
|
|
132
|
-
/* @__PURE__ */
|
|
132
|
+
/* @__PURE__ */ w(d, {
|
|
133
133
|
label: j("devportal.organizationName", "Organization Name"),
|
|
134
134
|
value: Y.name,
|
|
135
|
-
onChange:
|
|
135
|
+
onChange: se,
|
|
136
136
|
placeholder: j("devportal.organizationNamePlaceholder", "Acme Development"),
|
|
137
137
|
required: !0,
|
|
138
138
|
error: M.name,
|
|
139
139
|
hint: j("devportal.organizationNameHint", "Your organization's display name")
|
|
140
140
|
}),
|
|
141
|
-
/* @__PURE__ */
|
|
141
|
+
/* @__PURE__ */ w(d, {
|
|
142
142
|
label: j("devportal.slug", "Slug"),
|
|
143
143
|
value: Y.slug,
|
|
144
144
|
onChange: (e) => $("slug", e.target.value.toLowerCase()),
|
|
@@ -147,48 +147,48 @@ var O = () => {
|
|
|
147
147
|
error: M.slug,
|
|
148
148
|
hint: j("devportal.slugHint", "URL-friendly identifier (auto-generated from name)")
|
|
149
149
|
}),
|
|
150
|
-
/* @__PURE__ */
|
|
150
|
+
/* @__PURE__ */ w(p, {
|
|
151
151
|
label: j("devportal.description", "Description"),
|
|
152
152
|
value: Y.description,
|
|
153
153
|
onChange: (e) => $("description", e.target.value),
|
|
154
154
|
placeholder: j("devportal.orgDescriptionPlaceholder", "Tell us about your organization..."),
|
|
155
155
|
rows: 3
|
|
156
156
|
}),
|
|
157
|
-
/* @__PURE__ */
|
|
157
|
+
/* @__PURE__ */ w(d, {
|
|
158
158
|
label: j("devportal.websiteUrl", "Website URL"),
|
|
159
159
|
type: "url",
|
|
160
160
|
value: Y.websiteUrl,
|
|
161
161
|
onChange: (e) => $("websiteUrl", e.target.value),
|
|
162
162
|
placeholder: "https://example.com"
|
|
163
163
|
}),
|
|
164
|
-
A && Z.length > 0 && /* @__PURE__ */
|
|
164
|
+
A && Z.length > 0 && /* @__PURE__ */ w(f, {
|
|
165
165
|
label: j("devportal.pickupPostalCode", "Pickup Pincode (optional)"),
|
|
166
166
|
value: Y.pickupPostalCode,
|
|
167
167
|
onChange: (e) => $("pickupPostalCode", e.target.value),
|
|
168
168
|
placeholder: j("devportal.pickupPostalCodeUseBilling", "Use billing account address"),
|
|
169
169
|
options: Z.map((e) => ({
|
|
170
170
|
value: e.postalCode,
|
|
171
|
-
label: `${e.label} — ${e.postalCode}`
|
|
171
|
+
label: `${e.label} — ${e.postalCode} · ${h(e.carrier)}`
|
|
172
172
|
})),
|
|
173
173
|
hint: j("devportal.pickupPostalCodeHint", "The postal code your physical orders actually ship from — used to quote real carrier shipping rates. You can skip this now and set it later from organization settings.")
|
|
174
174
|
}),
|
|
175
|
-
A && Z.length === 0 && /* @__PURE__ */
|
|
175
|
+
A && Z.length === 0 && /* @__PURE__ */ w(d, {
|
|
176
176
|
label: j("devportal.pickupPostalCode", "Pickup Pincode (optional)"),
|
|
177
177
|
value: Y.pickupPostalCode,
|
|
178
178
|
onChange: (e) => $("pickupPostalCode", e.target.value),
|
|
179
179
|
placeholder: "560001",
|
|
180
180
|
hint: j("devportal.pickupPostalCodeHintFallback", "The postal code your physical orders actually ship from — used to quote real carrier shipping rates. You can skip this now and set it later from organization settings. (Live pickup-location list unavailable — enter your pincode manually.)")
|
|
181
181
|
}),
|
|
182
|
-
/* @__PURE__ */
|
|
182
|
+
/* @__PURE__ */ T("div", {
|
|
183
183
|
className: "grid gap-4 sm:grid-cols-2",
|
|
184
|
-
children: [/* @__PURE__ */
|
|
184
|
+
children: [/* @__PURE__ */ w(d, {
|
|
185
185
|
label: j("devportal.contactEmail", "Contact Email"),
|
|
186
186
|
type: "email",
|
|
187
187
|
value: Y.contactEmail,
|
|
188
188
|
onChange: (e) => $("contactEmail", e.target.value),
|
|
189
189
|
placeholder: "contact@example.com",
|
|
190
190
|
error: M.contactEmail
|
|
191
|
-
}), /* @__PURE__ */
|
|
191
|
+
}), /* @__PURE__ */ w(d, {
|
|
192
192
|
label: j("devportal.supportEmail", "Support Email"),
|
|
193
193
|
type: "email",
|
|
194
194
|
value: Y.supportEmail,
|
|
@@ -200,66 +200,66 @@ var O = () => {
|
|
|
200
200
|
]
|
|
201
201
|
})
|
|
202
202
|
}),
|
|
203
|
-
/* @__PURE__ */
|
|
203
|
+
/* @__PURE__ */ w(u, {
|
|
204
204
|
title: j("devportal.billingAccount", "Billing Account"),
|
|
205
205
|
description: j("devportal.billingAccountSectionDescription", "Revenue from sales will be credited here. You can change this anytime from the Revenue page."),
|
|
206
|
-
children: /* @__PURE__ */
|
|
206
|
+
children: /* @__PURE__ */ T("div", {
|
|
207
207
|
className: "space-y-3",
|
|
208
208
|
children: [
|
|
209
|
-
/* @__PURE__ */
|
|
209
|
+
/* @__PURE__ */ T("button", {
|
|
210
210
|
type: "button",
|
|
211
211
|
onClick: () => U("auto"),
|
|
212
212
|
disabled: V,
|
|
213
213
|
className: n("flex w-full items-start gap-3 rounded-lg border px-4 py-3 text-left transition-colors disabled:cursor-not-allowed disabled:opacity-50", H === "auto" ? "border-primary bg-action-primary-bg/5" : "border-border-subtle hover:bg-bg-sunken"),
|
|
214
|
-
children: [/* @__PURE__ */
|
|
214
|
+
children: [/* @__PURE__ */ w(b, {
|
|
215
215
|
size: 16,
|
|
216
216
|
className: n("mt-0.5 flex-shrink-0", H === "auto" ? "opacity-100 text-primary" : "opacity-0")
|
|
217
|
-
}), /* @__PURE__ */
|
|
217
|
+
}), /* @__PURE__ */ T("div", {
|
|
218
218
|
className: "flex-1 min-w-0",
|
|
219
|
-
children: [/* @__PURE__ */
|
|
219
|
+
children: [/* @__PURE__ */ w("p", {
|
|
220
220
|
className: "text-sm font-medium",
|
|
221
221
|
children: j("devportal.billingAutoCreate", "Create a new billing account automatically")
|
|
222
|
-
}), /* @__PURE__ */
|
|
222
|
+
}), /* @__PURE__ */ w("p", {
|
|
223
223
|
className: "mt-0.5 text-xs text-text-secondary",
|
|
224
224
|
children: j("devportal.billingAutoCreateHint", "We'll set one up using your organization name and account email. You can complete legal and tax details for payouts later in Organization Settings.")
|
|
225
225
|
})]
|
|
226
226
|
})]
|
|
227
227
|
}),
|
|
228
|
-
/* @__PURE__ */
|
|
228
|
+
/* @__PURE__ */ T("button", {
|
|
229
229
|
type: "button",
|
|
230
230
|
onClick: () => U("existing"),
|
|
231
231
|
disabled: V || !q && J.length === 0,
|
|
232
232
|
className: n("flex w-full items-start gap-3 rounded-lg border px-4 py-3 text-left transition-colors disabled:cursor-not-allowed disabled:opacity-50", H === "existing" ? "border-primary bg-action-primary-bg/5" : "border-border-subtle hover:bg-bg-sunken"),
|
|
233
|
-
children: [/* @__PURE__ */
|
|
233
|
+
children: [/* @__PURE__ */ w(b, {
|
|
234
234
|
size: 16,
|
|
235
235
|
className: n("mt-0.5 flex-shrink-0", H === "existing" ? "opacity-100 text-primary" : "opacity-0")
|
|
236
|
-
}), /* @__PURE__ */
|
|
236
|
+
}), /* @__PURE__ */ T("div", {
|
|
237
237
|
className: "flex-1 min-w-0",
|
|
238
|
-
children: [/* @__PURE__ */
|
|
238
|
+
children: [/* @__PURE__ */ T("p", {
|
|
239
239
|
className: "flex items-center gap-1.5 text-sm font-medium",
|
|
240
|
-
children: [/* @__PURE__ */
|
|
241
|
-
}), /* @__PURE__ */
|
|
240
|
+
children: [/* @__PURE__ */ w(re, { size: 14 }), j("devportal.billingLinkExisting", "Link an existing billing account")]
|
|
241
|
+
}), /* @__PURE__ */ w("p", {
|
|
242
242
|
className: "mt-0.5 text-xs text-text-secondary",
|
|
243
243
|
children: q ? j("devportal.billingAccountsLoading", "Loading your billing accounts...") : J.length === 0 ? j("devportal.noBillingAccountsYet", "You don't have any billing accounts yet — create one from account billing settings first.") : j("devportal.billingAccountsAvailable", "{{count}} billing account(s) available to link", { count: J.length })
|
|
244
244
|
})]
|
|
245
245
|
})]
|
|
246
246
|
}),
|
|
247
|
-
H === "existing" && J.length > 0 && /* @__PURE__ */
|
|
247
|
+
H === "existing" && J.length > 0 && /* @__PURE__ */ w("div", {
|
|
248
248
|
className: "ml-8 space-y-2",
|
|
249
|
-
children: J.map((e) => /* @__PURE__ */
|
|
249
|
+
children: J.map((e) => /* @__PURE__ */ T("button", {
|
|
250
250
|
type: "button",
|
|
251
251
|
disabled: V,
|
|
252
252
|
onClick: () => G(e.id ?? null),
|
|
253
253
|
className: n("flex w-full items-center gap-3 rounded-md border px-3 py-2 text-left text-sm transition-colors disabled:cursor-not-allowed disabled:opacity-50", W === e.id ? "border-primary bg-action-primary-bg/5" : "border-border-subtle hover:bg-bg-sunken"),
|
|
254
|
-
children: [/* @__PURE__ */
|
|
254
|
+
children: [/* @__PURE__ */ w(b, {
|
|
255
255
|
size: 14,
|
|
256
256
|
className: n("flex-shrink-0", W === e.id ? "opacity-100 text-primary" : "opacity-0")
|
|
257
|
-
}), /* @__PURE__ */
|
|
257
|
+
}), /* @__PURE__ */ T("div", {
|
|
258
258
|
className: "min-w-0 flex-1",
|
|
259
|
-
children: [/* @__PURE__ */
|
|
259
|
+
children: [/* @__PURE__ */ w("p", {
|
|
260
260
|
className: "truncate font-medium",
|
|
261
261
|
children: e.name
|
|
262
|
-
}), e.isDefault && /* @__PURE__ */
|
|
262
|
+
}), e.isDefault && /* @__PURE__ */ w("p", {
|
|
263
263
|
className: "text-xs text-text-secondary",
|
|
264
264
|
children: j("devportal.revenue.defaultAccount", "Default")
|
|
265
265
|
})]
|
|
@@ -269,10 +269,10 @@ var O = () => {
|
|
|
269
269
|
]
|
|
270
270
|
})
|
|
271
271
|
}),
|
|
272
|
-
V && /* @__PURE__ */
|
|
272
|
+
V && /* @__PURE__ */ T("div", {
|
|
273
273
|
className: "flex items-center gap-2 rounded-lg border border-border-subtle bg-bg-sunken px-4 py-3 text-sm text-text-secondary",
|
|
274
274
|
children: [
|
|
275
|
-
/* @__PURE__ */
|
|
275
|
+
/* @__PURE__ */ w(x, {
|
|
276
276
|
size: 16,
|
|
277
277
|
className: "flex-shrink-0 animate-spin text-primary"
|
|
278
278
|
}),
|
|
@@ -282,26 +282,26 @@ var O = () => {
|
|
|
282
282
|
z === "redirecting" && j("devportal.redirectingStatus", "All set — redirecting...")
|
|
283
283
|
]
|
|
284
284
|
}),
|
|
285
|
-
/* @__PURE__ */
|
|
285
|
+
/* @__PURE__ */ T("div", {
|
|
286
286
|
className: "flex items-center justify-end gap-3 border-t pt-6",
|
|
287
|
-
children: [/* @__PURE__ */
|
|
287
|
+
children: [/* @__PURE__ */ T("button", {
|
|
288
288
|
type: "button",
|
|
289
289
|
onClick: () => {
|
|
290
290
|
Q(i(A));
|
|
291
291
|
},
|
|
292
292
|
disabled: V,
|
|
293
293
|
className: "inline-flex items-center gap-2 rounded-md border px-4 py-2 text-sm font-medium hover:bg-bg-sunken transition-colors disabled:opacity-50",
|
|
294
|
-
children: [/* @__PURE__ */
|
|
295
|
-
}), /* @__PURE__ */
|
|
294
|
+
children: [/* @__PURE__ */ w(S, { size: 16 }), j("devportal.cancel", "Cancel")]
|
|
295
|
+
}), /* @__PURE__ */ w("button", {
|
|
296
296
|
type: "submit",
|
|
297
297
|
disabled: V,
|
|
298
298
|
className: "inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors disabled:opacity-50",
|
|
299
|
-
children: V ? /* @__PURE__ */
|
|
300
|
-
/* @__PURE__ */
|
|
299
|
+
children: V ? /* @__PURE__ */ T(C, { children: [
|
|
300
|
+
/* @__PURE__ */ w("span", { className: "h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent" }),
|
|
301
301
|
z === "setting-up-billing" && j("devportal.settingUpBilling", "Setting up billing..."),
|
|
302
302
|
z === "linking-billing" && j("devportal.linkingBilling", "Linking billing..."),
|
|
303
303
|
(z === "creating-org" || z === "redirecting") && j("devportal.creating", "Creating...")
|
|
304
|
-
] }) : /* @__PURE__ */
|
|
304
|
+
] }) : /* @__PURE__ */ T(C, { children: [/* @__PURE__ */ w(ne, { size: 16 }), j("devportal.createOrganization", "Create Organization")] })
|
|
305
305
|
})]
|
|
306
306
|
})
|
|
307
307
|
]
|
|
@@ -310,6 +310,6 @@ var O = () => {
|
|
|
310
310
|
});
|
|
311
311
|
};
|
|
312
312
|
//#endregion
|
|
313
|
-
export {
|
|
313
|
+
export { E as CreateOrganizationPage };
|
|
314
314
|
|
|
315
315
|
//# sourceMappingURL=CreateOrganizationPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateOrganizationPage.js","names":[],"sources":["../../../src/devportal/pages/CreateOrganizationPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { X, Building2, Check, Link2, Loader2 } from \"lucide-react\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport {\n InputField,\n TextareaField,\n SelectField,\n} from \"../components/FormField\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport {\n useIsSellerSection,\n orgSectionPath,\n} from \"../hooks/useIsSellerSection\";\nimport { useCarrierPickupLocations } from \"../hooks/useCarrierPickupLocations\";\nimport {\n useCreateOrganizationMutation,\n useCreateSellerOrganizationMutation,\n useGetBillingAccountsByOrgQuery,\n useLinkDevOrgBillingAccountMutation,\n} from \"../../generated/global-operations\";\nimport { useCreateBillingAccountMutation } from \"../hooks\";\nimport { useDevportalEventBus } from \"../events\";\nimport { cn } from \"../utils/cn\";\nimport { useTr } from \"../utils/i18n\";\n\ninterface CreateOrganizationFormData {\n name: string;\n slug: string;\n description: string;\n websiteUrl: string;\n contactEmail: string;\n supportEmail: string;\n /** PHYSICAL (seller) orgs only — optional, can be set/changed later too. */\n pickupPostalCode: string;\n}\n\ninterface FormErrors {\n name?: string;\n slug?: string;\n contactEmail?: string;\n supportEmail?: string;\n}\n\ntype SubmitPhase =\n | \"idle\"\n | \"creating-org\"\n | \"setting-up-billing\"\n | \"linking-billing\"\n | \"redirecting\";\n\n/**\n * Create new organization page — single step.\n * The user can either have a billing account auto-created and linked, or\n * link one of their existing billing accounts up front. Legal/tax details\n * are completed later from organization settings.\n */\nexport const CreateOrganizationPage: FC = () => {\n const {\n navigate,\n basePath,\n currentUser,\n tenantId,\n setActiveOrgId,\n setActivePhysicalOrgId,\n } = useDevportal();\n const isSeller = useIsSellerSection();\n const tr = useTr();\n const [errors, setErrors] = useState<FormErrors>({});\n // Shared page for both kinds — which mutation runs is the trust boundary\n // for DeveloperOrgKind (BOFF-7285): createSellerOrganization always makes\n // a PHYSICAL org, createDeveloperOrganization always makes DIGITAL. Both\n // hooks are called unconditionally (rules of hooks); only one is invoked.\n const [createOrganization] = useCreateOrganizationMutation();\n const [createSellerOrganization] = useCreateSellerOrganizationMutation();\n const [createBillingAccountMutation] = useCreateBillingAccountMutation();\n const [linkBillingAccount] = useLinkDevOrgBillingAccountMutation();\n const bus = useDevportalEventBus();\n\n // Multi-step status so the button/banner reflect the whole create flow —\n // not just the org-creation mutation's own loading flag, which flips back\n // to false before the (awaited) billing setup/link steps finish.\n const [phase, setPhase] = useState<SubmitPhase>(\"idle\");\n const isSubmitting = phase !== \"idle\";\n\n const [billingChoice, setBillingChoice] = useState<\"auto\" | \"existing\">(\n \"auto\",\n );\n const [selectedBillingAccountId, setSelectedBillingAccountId] = useState<\n string | null\n >(null);\n const { data: billingAccountsData, loading: billingAccountsLoading } =\n useGetBillingAccountsByOrgQuery({\n fetchPolicy: \"cache-and-network\",\n context: { headers: { \"x-org-id\": tenantId ?? \"\" } },\n });\n type BillingAccount = NonNullable<\n typeof billingAccountsData\n >[\"getBillingAccountsByOrg\"][number];\n const existingBillingAccounts: BillingAccount[] = useMemo(\n () => billingAccountsData?.getBillingAccountsByOrg ?? [],\n [billingAccountsData],\n );\n\n // Keep the \"existing account\" choice valid as the list loads: fall back to\n // auto-create if it turns out empty, and default-select once it arrives.\n useEffect(() => {\n if (billingChoice !== \"existing\" || billingAccountsLoading) return;\n if (existingBillingAccounts.length === 0) {\n setBillingChoice(\"auto\");\n return;\n }\n if (!selectedBillingAccountId) {\n setSelectedBillingAccountId(\n existingBillingAccounts.find((a) => a.isDefault)?.id ??\n existingBillingAccounts[0]?.id ??\n null,\n );\n }\n }, [\n billingChoice,\n billingAccountsLoading,\n existingBillingAccounts,\n selectedBillingAccountId,\n ]);\n\n const [formData, setFormData] = useState<CreateOrganizationFormData>({\n name: \"\",\n slug: \"\",\n description: \"\",\n websiteUrl: \"\",\n contactEmail: \"\",\n supportEmail: \"\",\n pickupPostalCode: \"\",\n });\n const { locations: pickupLocations } = useCarrierPickupLocations();\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n const generateSlug = (name: string): string => {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n };\n\n const handleNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const name = e.target.value;\n setFormData((prev) => ({\n ...prev,\n name,\n slug: prev.slug || generateSlug(name),\n }));\n if (errors.name) {\n setErrors((prev) => ({ ...prev, name: undefined }));\n }\n };\n\n const handleChange = (\n field: keyof CreateOrganizationFormData,\n value: string,\n ) => {\n setFormData((prev) => ({ ...prev, [field]: value }));\n if (errors[field as keyof FormErrors]) {\n setErrors((prev) => ({ ...prev, [field]: undefined }));\n }\n };\n\n const validate = (): boolean => {\n const newErrors: FormErrors = {};\n\n if (!formData.name.trim()) {\n newErrors.name = tr(\n \"devportal.orgNameRequired\",\n \"Organization name is required\",\n );\n } else if (formData.name.length < 2) {\n newErrors.name = tr(\n \"devportal.orgNameTooShort\",\n \"Name must be at least 2 characters\",\n );\n } else if (formData.name.length > 100) {\n newErrors.name = tr(\n \"devportal.nameTooLong\",\n \"Name must be less than 100 characters\",\n );\n }\n\n if (!formData.slug.trim()) {\n newErrors.slug = tr(\"devportal.slugRequired\", \"Slug is required\");\n } else if (!/^[a-z0-9-]+$/.test(formData.slug)) {\n newErrors.slug = tr(\n \"devportal.slugInvalid\",\n \"Slug can only contain lowercase letters, numbers, and hyphens\",\n );\n }\n\n if (\n formData.contactEmail &&\n !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(formData.contactEmail)\n ) {\n newErrors.contactEmail = tr(\n \"devportal.invalidEmailAddress\",\n \"Invalid email address\",\n );\n }\n\n if (\n formData.supportEmail &&\n !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(formData.supportEmail)\n ) {\n newErrors.supportEmail = tr(\n \"devportal.invalidEmailAddress\",\n \"Invalid email address\",\n );\n }\n\n setErrors(newErrors);\n return Object.keys(newErrors).length === 0;\n };\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n if (!validate()) return;\n\n setPhase(\"creating-org\");\n try {\n const input = {\n name: formData.name,\n slug: formData.slug || undefined,\n description: formData.description || undefined,\n websiteUrl: formData.websiteUrl || undefined,\n contactEmail: formData.contactEmail || undefined,\n supportEmail: formData.supportEmail || undefined,\n // Only meaningful for PHYSICAL (seller) orgs — harmless to send\n // for DIGITAL orgs too since it's just left unset there.\n pickupPostalCode:\n (isSeller && formData.pickupPostalCode.trim()) || undefined,\n };\n\n const orgId = isSeller\n ? (await createSellerOrganization({ variables: { input } })).data\n ?.createSellerOrganization?.id\n : (await createOrganization({ variables: { input } })).data\n ?.createDeveloperOrganization?.id;\n\n if (!orgId) {\n setPhase(\"idle\");\n return;\n }\n\n bus.emit(\"devportal.org.created\", {\n organizationId: orgId,\n name: formData.name,\n });\n if (isSeller) {\n setActivePhysicalOrgId(orgId);\n } else {\n setActiveOrgId(orgId);\n }\n\n if (billingChoice === \"existing\" && selectedBillingAccountId) {\n setPhase(\"linking-billing\");\n try {\n await linkBillingAccount({\n variables: {\n organizationId: orgId,\n billingAccountId: selectedBillingAccountId,\n },\n });\n } catch {\n // non-blocking — can be linked later from the Revenue tab\n }\n } else {\n setPhase(\"setting-up-billing\");\n try {\n const billingResult = await createBillingAccountMutation({\n variables: {\n input: {\n name: formData.name,\n email: currentUser?.email ?? \"\",\n },\n },\n });\n const billingAccountId = billingResult.data?.createBillingAccount?.id;\n if (billingAccountId) {\n await linkBillingAccount({\n variables: { organizationId: orgId, billingAccountId },\n });\n }\n } catch {\n // non-blocking — can be linked later from the Revenue tab\n }\n }\n\n setPhase(\"redirecting\");\n handleNavigate(orgSectionPath(isSeller, orgId));\n } catch (error) {\n console.error(\"Failed to create organization:\", error);\n setPhase(\"idle\");\n }\n };\n\n const handleCancel = () => {\n handleNavigate(orgSectionPath(isSeller));\n };\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={tr(\"devportal.createOrganization\", \"Create Organization\")}\n description={\n isSeller\n ? tr(\n \"devportal.createSellerOrganizationDescription\",\n \"Set up a seller organization to start selling physical products\",\n )\n : tr(\n \"devportal.createOrganizationDescription\",\n \"Set up a developer organization to collaborate with your team\",\n )\n }\n purpose={\n isSeller\n ? tr(\n \"devportal.createSellerOrganizationPurpose\",\n \"A seller organization is the shared owner of your physical listings, orders, and revenue. Create one here — you can invite members and complete legal/tax details afterwards.\",\n )\n : tr(\n \"devportal.createOrganizationPurpose\",\n \"An organization is the shared owner of your apps, members, and revenue. Create one here so your team works under a single identity — pick a name and tier now; you can invite members and verify it afterwards.\",\n )\n }\n backLink={`${basePath}${orgSectionPath(isSeller)}`}\n backLabel={tr(\"devportal.backToOrganizations\", \"Back to Organizations\")}\n >\n <form onSubmit={handleSubmit} className=\"space-y-8 max-w-3xl\">\n {/* Organization Details */}\n <PageSection\n title={tr(\"devportal.organizationDetails\", \"Organization Details\")}\n description={tr(\n \"devportal.organizationDetailsDescription\",\n \"Basic information about your organization\",\n )}\n >\n <div className=\"space-y-4\">\n <InputField\n label={tr(\"devportal.organizationName\", \"Organization Name\")}\n value={formData.name}\n onChange={handleNameChange}\n placeholder={tr(\n \"devportal.organizationNamePlaceholder\",\n \"Acme Development\",\n )}\n required\n error={errors.name}\n hint={tr(\n \"devportal.organizationNameHint\",\n \"Your organization's display name\",\n )}\n />\n\n <InputField\n label={tr(\"devportal.slug\", \"Slug\")}\n value={formData.slug}\n onChange={(e) =>\n handleChange(\"slug\", e.target.value.toLowerCase())\n }\n placeholder={tr(\"devportal.orgSlugPlaceholder\", \"acme-dev\")}\n required\n error={errors.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={formData.description}\n onChange={(e) => handleChange(\"description\", e.target.value)}\n placeholder={tr(\n \"devportal.orgDescriptionPlaceholder\",\n \"Tell us about your organization...\",\n )}\n rows={3}\n />\n\n <InputField\n label={tr(\"devportal.websiteUrl\", \"Website URL\")}\n type=\"url\"\n value={formData.websiteUrl}\n onChange={(e) => handleChange(\"websiteUrl\", e.target.value)}\n placeholder=\"https://example.com\"\n />\n\n {isSeller && pickupLocations.length > 0 && (\n <SelectField\n label={tr(\n \"devportal.pickupPostalCode\",\n \"Pickup Pincode (optional)\",\n )}\n value={formData.pickupPostalCode}\n onChange={(e) =>\n handleChange(\"pickupPostalCode\", e.target.value)\n }\n placeholder={tr(\n \"devportal.pickupPostalCodeUseBilling\",\n \"Use billing account address\",\n )}\n options={pickupLocations.map((location) => ({\n value: location.postalCode,\n label: `${location.label} — ${location.postalCode}`,\n }))}\n hint={tr(\n \"devportal.pickupPostalCodeHint\",\n \"The postal code your physical orders actually ship from — used to quote real carrier shipping rates. You can skip this now and set it later from organization settings.\",\n )}\n />\n )}\n {isSeller && pickupLocations.length === 0 && (\n <InputField\n label={tr(\n \"devportal.pickupPostalCode\",\n \"Pickup Pincode (optional)\",\n )}\n value={formData.pickupPostalCode}\n onChange={(e) =>\n handleChange(\"pickupPostalCode\", e.target.value)\n }\n placeholder=\"560001\"\n hint={tr(\n \"devportal.pickupPostalCodeHintFallback\",\n \"The postal code your physical orders actually ship from — used to quote real carrier shipping rates. You can skip this now and set it later from organization settings. (Live pickup-location list unavailable — enter your pincode manually.)\",\n )}\n />\n )}\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <InputField\n label={tr(\"devportal.contactEmail\", \"Contact Email\")}\n type=\"email\"\n value={formData.contactEmail}\n onChange={(e) => handleChange(\"contactEmail\", e.target.value)}\n placeholder=\"contact@example.com\"\n error={errors.contactEmail}\n />\n\n <InputField\n label={tr(\"devportal.supportEmail\", \"Support Email\")}\n type=\"email\"\n value={formData.supportEmail}\n onChange={(e) => handleChange(\"supportEmail\", e.target.value)}\n placeholder=\"support@example.com\"\n error={errors.supportEmail}\n />\n </div>\n </div>\n </PageSection>\n\n {/* Billing Account */}\n <PageSection\n title={tr(\"devportal.billingAccount\", \"Billing Account\")}\n description={tr(\n \"devportal.billingAccountSectionDescription\",\n \"Revenue from sales will be credited here. You can change this anytime from the Revenue page.\",\n )}\n >\n <div className=\"space-y-3\">\n <button\n type=\"button\"\n onClick={() => setBillingChoice(\"auto\")}\n disabled={isSubmitting}\n className={cn(\n \"flex w-full items-start gap-3 rounded-lg border px-4 py-3 text-left transition-colors disabled:cursor-not-allowed disabled:opacity-50\",\n billingChoice === \"auto\"\n ? \"border-primary bg-action-primary-bg/5\"\n : \"border-border-subtle hover:bg-bg-sunken\",\n )}\n >\n <Check\n size={16}\n className={cn(\n \"mt-0.5 flex-shrink-0\",\n billingChoice === \"auto\"\n ? \"opacity-100 text-primary\"\n : \"opacity-0\",\n )}\n />\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium\">\n {tr(\n \"devportal.billingAutoCreate\",\n \"Create a new billing account automatically\",\n )}\n </p>\n <p className=\"mt-0.5 text-xs text-text-secondary\">\n {tr(\n \"devportal.billingAutoCreateHint\",\n \"We'll set one up using your organization name and account email. You can complete legal and tax details for payouts later in Organization Settings.\",\n )}\n </p>\n </div>\n </button>\n\n <button\n type=\"button\"\n onClick={() => setBillingChoice(\"existing\")}\n disabled={\n isSubmitting ||\n (!billingAccountsLoading &&\n existingBillingAccounts.length === 0)\n }\n className={cn(\n \"flex w-full items-start gap-3 rounded-lg border px-4 py-3 text-left transition-colors disabled:cursor-not-allowed disabled:opacity-50\",\n billingChoice === \"existing\"\n ? \"border-primary bg-action-primary-bg/5\"\n : \"border-border-subtle hover:bg-bg-sunken\",\n )}\n >\n <Check\n size={16}\n className={cn(\n \"mt-0.5 flex-shrink-0\",\n billingChoice === \"existing\"\n ? \"opacity-100 text-primary\"\n : \"opacity-0\",\n )}\n />\n <div className=\"flex-1 min-w-0\">\n <p className=\"flex items-center gap-1.5 text-sm font-medium\">\n <Link2 size={14} />\n {tr(\n \"devportal.billingLinkExisting\",\n \"Link an existing billing account\",\n )}\n </p>\n <p className=\"mt-0.5 text-xs text-text-secondary\">\n {billingAccountsLoading\n ? tr(\n \"devportal.billingAccountsLoading\",\n \"Loading your billing accounts...\",\n )\n : existingBillingAccounts.length === 0\n ? tr(\n \"devportal.noBillingAccountsYet\",\n \"You don't have any billing accounts yet — create one from account billing settings first.\",\n )\n : tr(\n \"devportal.billingAccountsAvailable\",\n \"{{count}} billing account(s) available to link\",\n { count: existingBillingAccounts.length },\n )}\n </p>\n </div>\n </button>\n\n {billingChoice === \"existing\" &&\n existingBillingAccounts.length > 0 && (\n <div className=\"ml-8 space-y-2\">\n {existingBillingAccounts.map((account) => (\n <button\n key={account.id}\n type=\"button\"\n disabled={isSubmitting}\n onClick={() =>\n setSelectedBillingAccountId(account.id ?? null)\n }\n className={cn(\n \"flex w-full items-center gap-3 rounded-md border px-3 py-2 text-left text-sm transition-colors disabled:cursor-not-allowed disabled:opacity-50\",\n selectedBillingAccountId === account.id\n ? \"border-primary bg-action-primary-bg/5\"\n : \"border-border-subtle hover:bg-bg-sunken\",\n )}\n >\n <Check\n size={14}\n className={cn(\n \"flex-shrink-0\",\n selectedBillingAccountId === account.id\n ? \"opacity-100 text-primary\"\n : \"opacity-0\",\n )}\n />\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate font-medium\">{account.name}</p>\n {account.isDefault && (\n <p className=\"text-xs text-text-secondary\">\n {tr(\n \"devportal.revenue.defaultAccount\",\n \"Default\",\n )}\n </p>\n )}\n </div>\n </button>\n ))}\n </div>\n )}\n </div>\n </PageSection>\n\n {/* Status while creating org + setting up billing */}\n {isSubmitting && (\n <div className=\"flex items-center gap-2 rounded-lg border border-border-subtle bg-bg-sunken px-4 py-3 text-sm text-text-secondary\">\n <Loader2\n size={16}\n className=\"flex-shrink-0 animate-spin text-primary\"\n />\n {phase === \"creating-org\" &&\n tr(\n \"devportal.creatingOrgStatus\",\n \"Creating your organization...\",\n )}\n {phase === \"setting-up-billing\" &&\n tr(\n \"devportal.settingUpBillingStatus\",\n \"Setting up your billing account...\",\n )}\n {phase === \"linking-billing\" &&\n tr(\n \"devportal.linkingBillingStatus\",\n \"Linking your billing account...\",\n )}\n {phase === \"redirecting\" &&\n tr(\"devportal.redirectingStatus\", \"All set — redirecting...\")}\n </div>\n )}\n\n {/* Actions */}\n <div className=\"flex items-center justify-end gap-3 border-t pt-6\">\n <button\n type=\"button\"\n onClick={handleCancel}\n disabled={isSubmitting}\n className=\"inline-flex items-center gap-2 rounded-md border px-4 py-2 text-sm font-medium hover:bg-bg-sunken transition-colors disabled:opacity-50\"\n >\n <X size={16} />\n {tr(\"devportal.cancel\", \"Cancel\")}\n </button>\n <button\n type=\"submit\"\n disabled={isSubmitting}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors disabled:opacity-50\"\n >\n {isSubmitting ? (\n <>\n <span className=\"h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent\" />\n {phase === \"setting-up-billing\" &&\n tr(\"devportal.settingUpBilling\", \"Setting up billing...\")}\n {phase === \"linking-billing\" &&\n tr(\"devportal.linkingBilling\", \"Linking billing...\")}\n {(phase === \"creating-org\" || phase === \"redirecting\") &&\n tr(\"devportal.creating\", \"Creating...\")}\n </>\n ) : (\n <>\n <Building2 size={16} />\n {tr(\"devportal.createOrganization\", \"Create Organization\")}\n </>\n )}\n </button>\n </div>\n </form>\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CreateOrganizationPage.js","names":[],"sources":["../../../src/devportal/pages/CreateOrganizationPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { X, Building2, Check, Link2, Loader2 } from \"lucide-react\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport {\n InputField,\n TextareaField,\n SelectField,\n} from \"../components/FormField\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport {\n useIsSellerSection,\n orgSectionPath,\n} from \"../hooks/useIsSellerSection\";\nimport {\n useCarrierPickupLocations,\n capitalizeCarrierName,\n} from \"../hooks/useCarrierPickupLocations\";\nimport {\n useCreateOrganizationMutation,\n useCreateSellerOrganizationMutation,\n useGetBillingAccountsByOrgQuery,\n useLinkDevOrgBillingAccountMutation,\n} from \"../../generated/global-operations\";\nimport { useCreateBillingAccountMutation } from \"../hooks\";\nimport { useDevportalEventBus } from \"../events\";\nimport { cn } from \"../utils/cn\";\nimport { useTr } from \"../utils/i18n\";\n\ninterface CreateOrganizationFormData {\n name: string;\n slug: string;\n description: string;\n websiteUrl: string;\n contactEmail: string;\n supportEmail: string;\n /** PHYSICAL (seller) orgs only — optional, can be set/changed later too. */\n pickupPostalCode: string;\n}\n\ninterface FormErrors {\n name?: string;\n slug?: string;\n contactEmail?: string;\n supportEmail?: string;\n}\n\ntype SubmitPhase =\n | \"idle\"\n | \"creating-org\"\n | \"setting-up-billing\"\n | \"linking-billing\"\n | \"redirecting\";\n\n/**\n * Create new organization page — single step.\n * The user can either have a billing account auto-created and linked, or\n * link one of their existing billing accounts up front. Legal/tax details\n * are completed later from organization settings.\n */\nexport const CreateOrganizationPage: FC = () => {\n const {\n navigate,\n basePath,\n currentUser,\n tenantId,\n setActiveOrgId,\n setActivePhysicalOrgId,\n } = useDevportal();\n const isSeller = useIsSellerSection();\n const tr = useTr();\n const [errors, setErrors] = useState<FormErrors>({});\n // Shared page for both kinds — which mutation runs is the trust boundary\n // for DeveloperOrgKind (BOFF-7285): createSellerOrganization always makes\n // a PHYSICAL org, createDeveloperOrganization always makes DIGITAL. Both\n // hooks are called unconditionally (rules of hooks); only one is invoked.\n const [createOrganization] = useCreateOrganizationMutation();\n const [createSellerOrganization] = useCreateSellerOrganizationMutation();\n const [createBillingAccountMutation] = useCreateBillingAccountMutation();\n const [linkBillingAccount] = useLinkDevOrgBillingAccountMutation();\n const bus = useDevportalEventBus();\n\n // Multi-step status so the button/banner reflect the whole create flow —\n // not just the org-creation mutation's own loading flag, which flips back\n // to false before the (awaited) billing setup/link steps finish.\n const [phase, setPhase] = useState<SubmitPhase>(\"idle\");\n const isSubmitting = phase !== \"idle\";\n\n const [billingChoice, setBillingChoice] = useState<\"auto\" | \"existing\">(\n \"auto\",\n );\n const [selectedBillingAccountId, setSelectedBillingAccountId] = useState<\n string | null\n >(null);\n const { data: billingAccountsData, loading: billingAccountsLoading } =\n useGetBillingAccountsByOrgQuery({\n fetchPolicy: \"cache-and-network\",\n context: { headers: { \"x-org-id\": tenantId ?? \"\" } },\n });\n type BillingAccount = NonNullable<\n typeof billingAccountsData\n >[\"getBillingAccountsByOrg\"][number];\n const existingBillingAccounts: BillingAccount[] = useMemo(\n () => billingAccountsData?.getBillingAccountsByOrg ?? [],\n [billingAccountsData],\n );\n\n // Keep the \"existing account\" choice valid as the list loads: fall back to\n // auto-create if it turns out empty, and default-select once it arrives.\n useEffect(() => {\n if (billingChoice !== \"existing\" || billingAccountsLoading) return;\n if (existingBillingAccounts.length === 0) {\n setBillingChoice(\"auto\");\n return;\n }\n if (!selectedBillingAccountId) {\n setSelectedBillingAccountId(\n existingBillingAccounts.find((a) => a.isDefault)?.id ??\n existingBillingAccounts[0]?.id ??\n null,\n );\n }\n }, [\n billingChoice,\n billingAccountsLoading,\n existingBillingAccounts,\n selectedBillingAccountId,\n ]);\n\n const [formData, setFormData] = useState<CreateOrganizationFormData>({\n name: \"\",\n slug: \"\",\n description: \"\",\n websiteUrl: \"\",\n contactEmail: \"\",\n supportEmail: \"\",\n pickupPostalCode: \"\",\n });\n const { locations: pickupLocations } = useCarrierPickupLocations();\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n const generateSlug = (name: string): string => {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n };\n\n const handleNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const name = e.target.value;\n setFormData((prev) => ({\n ...prev,\n name,\n slug: prev.slug || generateSlug(name),\n }));\n if (errors.name) {\n setErrors((prev) => ({ ...prev, name: undefined }));\n }\n };\n\n const handleChange = (\n field: keyof CreateOrganizationFormData,\n value: string,\n ) => {\n setFormData((prev) => ({ ...prev, [field]: value }));\n if (errors[field as keyof FormErrors]) {\n setErrors((prev) => ({ ...prev, [field]: undefined }));\n }\n };\n\n const validate = (): boolean => {\n const newErrors: FormErrors = {};\n\n if (!formData.name.trim()) {\n newErrors.name = tr(\n \"devportal.orgNameRequired\",\n \"Organization name is required\",\n );\n } else if (formData.name.length < 2) {\n newErrors.name = tr(\n \"devportal.orgNameTooShort\",\n \"Name must be at least 2 characters\",\n );\n } else if (formData.name.length > 100) {\n newErrors.name = tr(\n \"devportal.nameTooLong\",\n \"Name must be less than 100 characters\",\n );\n }\n\n if (!formData.slug.trim()) {\n newErrors.slug = tr(\"devportal.slugRequired\", \"Slug is required\");\n } else if (!/^[a-z0-9-]+$/.test(formData.slug)) {\n newErrors.slug = tr(\n \"devportal.slugInvalid\",\n \"Slug can only contain lowercase letters, numbers, and hyphens\",\n );\n }\n\n if (\n formData.contactEmail &&\n !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(formData.contactEmail)\n ) {\n newErrors.contactEmail = tr(\n \"devportal.invalidEmailAddress\",\n \"Invalid email address\",\n );\n }\n\n if (\n formData.supportEmail &&\n !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(formData.supportEmail)\n ) {\n newErrors.supportEmail = tr(\n \"devportal.invalidEmailAddress\",\n \"Invalid email address\",\n );\n }\n\n setErrors(newErrors);\n return Object.keys(newErrors).length === 0;\n };\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n if (!validate()) return;\n\n setPhase(\"creating-org\");\n try {\n const input = {\n name: formData.name,\n slug: formData.slug || undefined,\n description: formData.description || undefined,\n websiteUrl: formData.websiteUrl || undefined,\n contactEmail: formData.contactEmail || undefined,\n supportEmail: formData.supportEmail || undefined,\n // Only meaningful for PHYSICAL (seller) orgs — harmless to send\n // for DIGITAL orgs too since it's just left unset there.\n pickupPostalCode:\n (isSeller && formData.pickupPostalCode.trim()) || undefined,\n };\n\n const orgId = isSeller\n ? (await createSellerOrganization({ variables: { input } })).data\n ?.createSellerOrganization?.id\n : (await createOrganization({ variables: { input } })).data\n ?.createDeveloperOrganization?.id;\n\n if (!orgId) {\n setPhase(\"idle\");\n return;\n }\n\n bus.emit(\"devportal.org.created\", {\n organizationId: orgId,\n name: formData.name,\n });\n if (isSeller) {\n setActivePhysicalOrgId(orgId);\n } else {\n setActiveOrgId(orgId);\n }\n\n if (billingChoice === \"existing\" && selectedBillingAccountId) {\n setPhase(\"linking-billing\");\n try {\n await linkBillingAccount({\n variables: {\n organizationId: orgId,\n billingAccountId: selectedBillingAccountId,\n },\n });\n } catch {\n // non-blocking — can be linked later from the Revenue tab\n }\n } else {\n setPhase(\"setting-up-billing\");\n try {\n const billingResult = await createBillingAccountMutation({\n variables: {\n input: {\n name: formData.name,\n email: currentUser?.email ?? \"\",\n },\n },\n });\n const billingAccountId = billingResult.data?.createBillingAccount?.id;\n if (billingAccountId) {\n await linkBillingAccount({\n variables: { organizationId: orgId, billingAccountId },\n });\n }\n } catch {\n // non-blocking — can be linked later from the Revenue tab\n }\n }\n\n setPhase(\"redirecting\");\n handleNavigate(orgSectionPath(isSeller, orgId));\n } catch (error) {\n console.error(\"Failed to create organization:\", error);\n setPhase(\"idle\");\n }\n };\n\n const handleCancel = () => {\n handleNavigate(orgSectionPath(isSeller));\n };\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={tr(\"devportal.createOrganization\", \"Create Organization\")}\n description={\n isSeller\n ? tr(\n \"devportal.createSellerOrganizationDescription\",\n \"Set up a seller organization to start selling physical products\",\n )\n : tr(\n \"devportal.createOrganizationDescription\",\n \"Set up a developer organization to collaborate with your team\",\n )\n }\n purpose={\n isSeller\n ? tr(\n \"devportal.createSellerOrganizationPurpose\",\n \"A seller organization is the shared owner of your physical listings, orders, and revenue. Create one here — you can invite members and complete legal/tax details afterwards.\",\n )\n : tr(\n \"devportal.createOrganizationPurpose\",\n \"An organization is the shared owner of your apps, members, and revenue. Create one here so your team works under a single identity — pick a name and tier now; you can invite members and verify it afterwards.\",\n )\n }\n backLink={`${basePath}${orgSectionPath(isSeller)}`}\n backLabel={tr(\"devportal.backToOrganizations\", \"Back to Organizations\")}\n >\n <form onSubmit={handleSubmit} className=\"space-y-8 max-w-3xl\">\n {/* Organization Details */}\n <PageSection\n title={tr(\"devportal.organizationDetails\", \"Organization Details\")}\n description={tr(\n \"devportal.organizationDetailsDescription\",\n \"Basic information about your organization\",\n )}\n >\n <div className=\"space-y-4\">\n <InputField\n label={tr(\"devportal.organizationName\", \"Organization Name\")}\n value={formData.name}\n onChange={handleNameChange}\n placeholder={tr(\n \"devportal.organizationNamePlaceholder\",\n \"Acme Development\",\n )}\n required\n error={errors.name}\n hint={tr(\n \"devportal.organizationNameHint\",\n \"Your organization's display name\",\n )}\n />\n\n <InputField\n label={tr(\"devportal.slug\", \"Slug\")}\n value={formData.slug}\n onChange={(e) =>\n handleChange(\"slug\", e.target.value.toLowerCase())\n }\n placeholder={tr(\"devportal.orgSlugPlaceholder\", \"acme-dev\")}\n required\n error={errors.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={formData.description}\n onChange={(e) => handleChange(\"description\", e.target.value)}\n placeholder={tr(\n \"devportal.orgDescriptionPlaceholder\",\n \"Tell us about your organization...\",\n )}\n rows={3}\n />\n\n <InputField\n label={tr(\"devportal.websiteUrl\", \"Website URL\")}\n type=\"url\"\n value={formData.websiteUrl}\n onChange={(e) => handleChange(\"websiteUrl\", e.target.value)}\n placeholder=\"https://example.com\"\n />\n\n {isSeller && pickupLocations.length > 0 && (\n <SelectField\n label={tr(\n \"devportal.pickupPostalCode\",\n \"Pickup Pincode (optional)\",\n )}\n value={formData.pickupPostalCode}\n onChange={(e) =>\n handleChange(\"pickupPostalCode\", e.target.value)\n }\n placeholder={tr(\n \"devportal.pickupPostalCodeUseBilling\",\n \"Use billing account address\",\n )}\n options={pickupLocations.map((location) => ({\n value: location.postalCode,\n label: `${location.label} — ${location.postalCode} · ${capitalizeCarrierName(location.carrier)}`,\n }))}\n hint={tr(\n \"devportal.pickupPostalCodeHint\",\n \"The postal code your physical orders actually ship from — used to quote real carrier shipping rates. You can skip this now and set it later from organization settings.\",\n )}\n />\n )}\n {isSeller && pickupLocations.length === 0 && (\n <InputField\n label={tr(\n \"devportal.pickupPostalCode\",\n \"Pickup Pincode (optional)\",\n )}\n value={formData.pickupPostalCode}\n onChange={(e) =>\n handleChange(\"pickupPostalCode\", e.target.value)\n }\n placeholder=\"560001\"\n hint={tr(\n \"devportal.pickupPostalCodeHintFallback\",\n \"The postal code your physical orders actually ship from — used to quote real carrier shipping rates. You can skip this now and set it later from organization settings. (Live pickup-location list unavailable — enter your pincode manually.)\",\n )}\n />\n )}\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <InputField\n label={tr(\"devportal.contactEmail\", \"Contact Email\")}\n type=\"email\"\n value={formData.contactEmail}\n onChange={(e) => handleChange(\"contactEmail\", e.target.value)}\n placeholder=\"contact@example.com\"\n error={errors.contactEmail}\n />\n\n <InputField\n label={tr(\"devportal.supportEmail\", \"Support Email\")}\n type=\"email\"\n value={formData.supportEmail}\n onChange={(e) => handleChange(\"supportEmail\", e.target.value)}\n placeholder=\"support@example.com\"\n error={errors.supportEmail}\n />\n </div>\n </div>\n </PageSection>\n\n {/* Billing Account */}\n <PageSection\n title={tr(\"devportal.billingAccount\", \"Billing Account\")}\n description={tr(\n \"devportal.billingAccountSectionDescription\",\n \"Revenue from sales will be credited here. You can change this anytime from the Revenue page.\",\n )}\n >\n <div className=\"space-y-3\">\n <button\n type=\"button\"\n onClick={() => setBillingChoice(\"auto\")}\n disabled={isSubmitting}\n className={cn(\n \"flex w-full items-start gap-3 rounded-lg border px-4 py-3 text-left transition-colors disabled:cursor-not-allowed disabled:opacity-50\",\n billingChoice === \"auto\"\n ? \"border-primary bg-action-primary-bg/5\"\n : \"border-border-subtle hover:bg-bg-sunken\",\n )}\n >\n <Check\n size={16}\n className={cn(\n \"mt-0.5 flex-shrink-0\",\n billingChoice === \"auto\"\n ? \"opacity-100 text-primary\"\n : \"opacity-0\",\n )}\n />\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium\">\n {tr(\n \"devportal.billingAutoCreate\",\n \"Create a new billing account automatically\",\n )}\n </p>\n <p className=\"mt-0.5 text-xs text-text-secondary\">\n {tr(\n \"devportal.billingAutoCreateHint\",\n \"We'll set one up using your organization name and account email. You can complete legal and tax details for payouts later in Organization Settings.\",\n )}\n </p>\n </div>\n </button>\n\n <button\n type=\"button\"\n onClick={() => setBillingChoice(\"existing\")}\n disabled={\n isSubmitting ||\n (!billingAccountsLoading &&\n existingBillingAccounts.length === 0)\n }\n className={cn(\n \"flex w-full items-start gap-3 rounded-lg border px-4 py-3 text-left transition-colors disabled:cursor-not-allowed disabled:opacity-50\",\n billingChoice === \"existing\"\n ? \"border-primary bg-action-primary-bg/5\"\n : \"border-border-subtle hover:bg-bg-sunken\",\n )}\n >\n <Check\n size={16}\n className={cn(\n \"mt-0.5 flex-shrink-0\",\n billingChoice === \"existing\"\n ? \"opacity-100 text-primary\"\n : \"opacity-0\",\n )}\n />\n <div className=\"flex-1 min-w-0\">\n <p className=\"flex items-center gap-1.5 text-sm font-medium\">\n <Link2 size={14} />\n {tr(\n \"devportal.billingLinkExisting\",\n \"Link an existing billing account\",\n )}\n </p>\n <p className=\"mt-0.5 text-xs text-text-secondary\">\n {billingAccountsLoading\n ? tr(\n \"devportal.billingAccountsLoading\",\n \"Loading your billing accounts...\",\n )\n : existingBillingAccounts.length === 0\n ? tr(\n \"devportal.noBillingAccountsYet\",\n \"You don't have any billing accounts yet — create one from account billing settings first.\",\n )\n : tr(\n \"devportal.billingAccountsAvailable\",\n \"{{count}} billing account(s) available to link\",\n { count: existingBillingAccounts.length },\n )}\n </p>\n </div>\n </button>\n\n {billingChoice === \"existing\" &&\n existingBillingAccounts.length > 0 && (\n <div className=\"ml-8 space-y-2\">\n {existingBillingAccounts.map((account) => (\n <button\n key={account.id}\n type=\"button\"\n disabled={isSubmitting}\n onClick={() =>\n setSelectedBillingAccountId(account.id ?? null)\n }\n className={cn(\n \"flex w-full items-center gap-3 rounded-md border px-3 py-2 text-left text-sm transition-colors disabled:cursor-not-allowed disabled:opacity-50\",\n selectedBillingAccountId === account.id\n ? \"border-primary bg-action-primary-bg/5\"\n : \"border-border-subtle hover:bg-bg-sunken\",\n )}\n >\n <Check\n size={14}\n className={cn(\n \"flex-shrink-0\",\n selectedBillingAccountId === account.id\n ? \"opacity-100 text-primary\"\n : \"opacity-0\",\n )}\n />\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate font-medium\">{account.name}</p>\n {account.isDefault && (\n <p className=\"text-xs text-text-secondary\">\n {tr(\n \"devportal.revenue.defaultAccount\",\n \"Default\",\n )}\n </p>\n )}\n </div>\n </button>\n ))}\n </div>\n )}\n </div>\n </PageSection>\n\n {/* Status while creating org + setting up billing */}\n {isSubmitting && (\n <div className=\"flex items-center gap-2 rounded-lg border border-border-subtle bg-bg-sunken px-4 py-3 text-sm text-text-secondary\">\n <Loader2\n size={16}\n className=\"flex-shrink-0 animate-spin text-primary\"\n />\n {phase === \"creating-org\" &&\n tr(\n \"devportal.creatingOrgStatus\",\n \"Creating your organization...\",\n )}\n {phase === \"setting-up-billing\" &&\n tr(\n \"devportal.settingUpBillingStatus\",\n \"Setting up your billing account...\",\n )}\n {phase === \"linking-billing\" &&\n tr(\n \"devportal.linkingBillingStatus\",\n \"Linking your billing account...\",\n )}\n {phase === \"redirecting\" &&\n tr(\"devportal.redirectingStatus\", \"All set — redirecting...\")}\n </div>\n )}\n\n {/* Actions */}\n <div className=\"flex items-center justify-end gap-3 border-t pt-6\">\n <button\n type=\"button\"\n onClick={handleCancel}\n disabled={isSubmitting}\n className=\"inline-flex items-center gap-2 rounded-md border px-4 py-2 text-sm font-medium hover:bg-bg-sunken transition-colors disabled:opacity-50\"\n >\n <X size={16} />\n {tr(\"devportal.cancel\", \"Cancel\")}\n </button>\n <button\n type=\"submit\"\n disabled={isSubmitting}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors disabled:opacity-50\"\n >\n {isSubmitting ? (\n <>\n <span className=\"h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent\" />\n {phase === \"setting-up-billing\" &&\n tr(\"devportal.settingUpBilling\", \"Setting up billing...\")}\n {phase === \"linking-billing\" &&\n tr(\"devportal.linkingBilling\", \"Linking billing...\")}\n {(phase === \"creating-org\" || phase === \"redirecting\") &&\n tr(\"devportal.creating\", \"Creating...\")}\n </>\n ) : (\n <>\n <Building2 size={16} />\n {tr(\"devportal.createOrganization\", \"Create Organization\")}\n </>\n )}\n </button>\n </div>\n </form>\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OrganizationDetailPage.d.ts","sourceRoot":"","sources":["../../../src/devportal/pages/OrganizationDetailPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"OrganizationDetailPage.d.ts","sourceRoot":"","sources":["../../../src/devportal/pages/OrganizationDetailPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AA2QhC;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,EAqVpC,CAAC"}
|