@burdenoff/microfe-devportal 2026.1101.1 → 2026.1107.1
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/DevportalRoutes.d.ts.map +1 -1
- package/dist/devportal/DevportalRoutes.js +13 -9
- package/dist/devportal/DevportalRoutes.js.map +1 -1
- package/dist/devportal/components/OnboardingChecklist.d.ts +16 -0
- package/dist/devportal/components/OnboardingChecklist.d.ts.map +1 -0
- package/dist/devportal/components/OnboardingChecklist.js +151 -0
- package/dist/devportal/components/OnboardingChecklist.js.map +1 -0
- package/dist/devportal/constants/developerLinks.d.ts +47 -0
- package/dist/devportal/constants/developerLinks.d.ts.map +1 -0
- package/dist/devportal/constants/developerLinks.js +27 -0
- package/dist/devportal/constants/developerLinks.js.map +1 -0
- package/dist/devportal/hooks/useGraphQL.d.ts.map +1 -1
- package/dist/devportal/hooks/useGraphQL.js +2 -1
- package/dist/devportal/hooks/useGraphQL.js.map +1 -1
- package/dist/devportal/hooks/usePackageUpload.d.ts +3 -0
- package/dist/devportal/hooks/usePackageUpload.d.ts.map +1 -1
- package/dist/devportal/hooks/usePackageUpload.js +41 -32
- package/dist/devportal/hooks/usePackageUpload.js.map +1 -1
- package/dist/devportal/pages/DashboardPage.d.ts.map +1 -1
- package/dist/devportal/pages/DashboardPage.js +107 -105
- package/dist/devportal/pages/DashboardPage.js.map +1 -1
- package/dist/devportal/pages/DocumentationPage.d.ts.map +1 -1
- package/dist/devportal/pages/DocumentationPage.js +114 -148
- package/dist/devportal/pages/DocumentationPage.js.map +1 -1
- package/dist/devportal/pages/PublisherProfilePage.d.ts.map +1 -1
- package/dist/devportal/pages/PublisherProfilePage.js +170 -160
- package/dist/devportal/pages/PublisherProfilePage.js.map +1 -1
- package/dist/devportal/pages/ResourcesPage.js +2 -2
- package/dist/devportal/pages/ResourcesPage.js.map +1 -1
- package/dist/devportal/pages/SetupPage.d.ts.map +1 -1
- package/dist/devportal/pages/SetupPage.js +363 -218
- package/dist/devportal/pages/SetupPage.js.map +1 -1
- package/dist/devportal/utils/developerOnboarding.d.ts +85 -0
- package/dist/devportal/utils/developerOnboarding.d.ts.map +1 -0
- package/dist/devportal/utils/developerOnboarding.js +104 -0
- package/dist/devportal/utils/developerOnboarding.js.map +1 -0
- package/dist/devportal/utils/uploadErrors.d.ts +46 -0
- package/dist/devportal/utils/uploadErrors.d.ts.map +1 -0
- package/dist/devportal/utils/uploadErrors.js +62 -0
- package/dist/devportal/utils/uploadErrors.js.map +1 -0
- package/dist/generated/global-operations.d.ts +53 -0
- package/dist/generated/global-operations.d.ts.map +1 -1
- package/dist/generated/global-operations.js +170 -134
- package/dist/generated/global-operations.js.map +1 -1
- package/dist/translations/en.d.ts +50 -0
- package/dist/translations/en.d.ts.map +1 -1
- package/dist/translations/en.js +51 -1
- package/dist/translations/en.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,259 +1,269 @@
|
|
|
1
1
|
import { useDevportal as e } from "../providers/DevportalProvider.js";
|
|
2
2
|
import { cn as t } from "../utils/cn.js";
|
|
3
|
-
import {
|
|
3
|
+
import { useCreateDeveloperProfileMutation as n, useGetMyDeveloperProfileQuery as r, useUpdateDeveloperProfileMutation as i } from "../../generated/global-operations.js";
|
|
4
4
|
import "../hooks/useGraphQL.js";
|
|
5
|
-
import { PageLayout as
|
|
6
|
-
import { InputField as
|
|
7
|
-
import { PermissionGuard as
|
|
5
|
+
import { PageLayout as a, PageSection as o } from "../components/PageLayout.js";
|
|
6
|
+
import { InputField as s } from "../components/FormField.js";
|
|
7
|
+
import { PermissionGuard as c } from "../components/PermissionGuard.js";
|
|
8
8
|
import "../components/index.js";
|
|
9
|
-
import { useDevportalPermission as
|
|
10
|
-
import { DEVPORTAL_PERMISSIONS as
|
|
11
|
-
import { useEffect as
|
|
12
|
-
import { AlertCircle as
|
|
13
|
-
import { jsx as
|
|
14
|
-
import { useI18n as
|
|
9
|
+
import { useDevportalPermission as l } from "../hooks/usePermission.js";
|
|
10
|
+
import { DEVPORTAL_PERMISSIONS as u } from "../constants/permissions.js";
|
|
11
|
+
import { useEffect as d, useState as f } from "react";
|
|
12
|
+
import { AlertCircle as p, CheckCircle2 as m, Info as h, Loader2 as g, Save as _, Store as v } from "lucide-react";
|
|
13
|
+
import { jsx as y, jsxs as b } from "react/jsx-runtime";
|
|
14
|
+
import { useI18n as x } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
15
15
|
//#region src/devportal/pages/PublisherProfilePage.tsx
|
|
16
|
-
var
|
|
17
|
-
let { t:
|
|
18
|
-
let n =
|
|
16
|
+
var S = () => {
|
|
17
|
+
let { t: S } = x(), C = (e, t) => {
|
|
18
|
+
let n = S(e);
|
|
19
19
|
return n === e ? t : n;
|
|
20
|
-
}, { currentUser:
|
|
21
|
-
return
|
|
22
|
-
if (
|
|
23
|
-
else if (!
|
|
24
|
-
let e = [
|
|
25
|
-
e &&
|
|
20
|
+
}, { currentUser: w } = e(), { allowed: T } = l(u.PROFILE_UPDATE), { data: E, loading: D, error: O, refetch: k } = r({ fetchPolicy: "cache-and-network" }), [A, { loading: j }] = i(), [M, { loading: N }] = n(), P = j || N, F = E?.myDeveloperProfile, [I, L] = f(""), [R, z] = f(""), [B, V] = f(""), [H, U] = f(""), [W, G] = f(""), [K, q] = f(""), [J, Y] = f("idle");
|
|
21
|
+
return d(() => {
|
|
22
|
+
if (F) L(F.companyName ?? ""), z(F.website ?? ""), V(F.bio ?? ""), U(F.githubUsername ?? ""), G(F.twitterUsername ?? ""), q(F.linkedinUrl ?? "");
|
|
23
|
+
else if (!D && w) {
|
|
24
|
+
let e = [w.firstName, w.lastName].filter(Boolean).join(" ");
|
|
25
|
+
e && L(e);
|
|
26
26
|
}
|
|
27
27
|
}, [
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
]),
|
|
32
|
-
title:
|
|
33
|
-
description:
|
|
34
|
-
children: /* @__PURE__ */
|
|
28
|
+
F,
|
|
29
|
+
D,
|
|
30
|
+
w
|
|
31
|
+
]), D && !F ? /* @__PURE__ */ y(a, {
|
|
32
|
+
title: C("devportal.publisherProfileTitle", "Publisher Profile"),
|
|
33
|
+
description: C("devportal.loadingPublisherProfile", "Loading your publisher profile..."),
|
|
34
|
+
children: /* @__PURE__ */ y("div", {
|
|
35
35
|
className: "flex items-center justify-center py-20",
|
|
36
|
-
children: /* @__PURE__ */
|
|
36
|
+
children: /* @__PURE__ */ y(g, { className: "h-8 w-8 animate-spin text-text-secondary" })
|
|
37
37
|
})
|
|
38
|
-
}) :
|
|
39
|
-
title:
|
|
40
|
-
description:
|
|
41
|
-
children: /* @__PURE__ */
|
|
38
|
+
}) : O && !F ? /* @__PURE__ */ y(a, {
|
|
39
|
+
title: C("devportal.publisherProfileTitle", "Publisher Profile"),
|
|
40
|
+
description: C("devportal.manageStorePublisherPresence", "Manage your store publisher presence"),
|
|
41
|
+
children: /* @__PURE__ */ b("div", {
|
|
42
42
|
className: "flex flex-col items-center justify-center gap-4 py-20",
|
|
43
43
|
children: [
|
|
44
|
-
/* @__PURE__ */
|
|
45
|
-
/* @__PURE__ */
|
|
44
|
+
/* @__PURE__ */ y(p, { className: "h-12 w-12 text-status-error-text" }),
|
|
45
|
+
/* @__PURE__ */ y("p", {
|
|
46
46
|
className: "text-text-secondary",
|
|
47
|
-
children:
|
|
47
|
+
children: C("devportal.failedToLoadProfile", "Failed to load profile")
|
|
48
48
|
}),
|
|
49
|
-
/* @__PURE__ */
|
|
50
|
-
onClick: () =>
|
|
49
|
+
/* @__PURE__ */ y("button", {
|
|
50
|
+
onClick: () => k(),
|
|
51
51
|
className: "rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
|
|
52
|
-
children:
|
|
52
|
+
children: C("devportal.retryButton", "Retry")
|
|
53
53
|
})
|
|
54
54
|
]
|
|
55
55
|
})
|
|
56
|
-
}) : /* @__PURE__ */
|
|
56
|
+
}) : /* @__PURE__ */ y(c, {
|
|
57
57
|
authOnly: !0,
|
|
58
|
-
children: /* @__PURE__ */
|
|
59
|
-
title:
|
|
60
|
-
description:
|
|
61
|
-
purpose:
|
|
62
|
-
actions: /* @__PURE__ */
|
|
58
|
+
children: /* @__PURE__ */ y(a, {
|
|
59
|
+
title: C("devportal.publisherProfileTitle", "Publisher Profile"),
|
|
60
|
+
description: C("devportal.manageMarketplaceAppearance", "Manage how you appear to users in the marketplace"),
|
|
61
|
+
purpose: C("devportal.publisherProfilePurpose", "This is your public face in the marketplace — the name, logo, bio, and links users see before installing your apps. A complete, trustworthy profile makes shoppers more likely to install and is required before some apps can be published."),
|
|
62
|
+
actions: /* @__PURE__ */ b("button", {
|
|
63
63
|
onClick: async () => {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
marketingEmails: j?.marketingEmails
|
|
79
|
-
}
|
|
80
|
-
} });
|
|
81
|
-
if (t.error) throw t.error;
|
|
82
|
-
G("saved"), await O(), setTimeout(() => G("idle"), 3e3);
|
|
83
|
-
} catch {
|
|
84
|
-
G("error"), setTimeout(() => G("idle"), 5e3);
|
|
64
|
+
Y("saving");
|
|
65
|
+
try {
|
|
66
|
+
if (!F) {
|
|
67
|
+
let e = await M({ variables: { input: {
|
|
68
|
+
companyName: I || void 0,
|
|
69
|
+
website: R || void 0,
|
|
70
|
+
bio: B || void 0,
|
|
71
|
+
githubUsername: H || void 0,
|
|
72
|
+
twitterUsername: W || void 0,
|
|
73
|
+
linkedinUrl: K || void 0
|
|
74
|
+
} } });
|
|
75
|
+
if (e.error) throw e.error;
|
|
76
|
+
Y("saved"), await k(), setTimeout(() => Y("idle"), 3e3);
|
|
77
|
+
return;
|
|
85
78
|
}
|
|
79
|
+
let e = await A({ variables: {
|
|
80
|
+
userId: F.userId,
|
|
81
|
+
input: {
|
|
82
|
+
companyName: I || null,
|
|
83
|
+
website: R || null,
|
|
84
|
+
bio: B || null,
|
|
85
|
+
githubUsername: H || null,
|
|
86
|
+
twitterUsername: W || null,
|
|
87
|
+
linkedinUrl: K || null,
|
|
88
|
+
emailNotifications: F.emailNotifications,
|
|
89
|
+
marketingEmails: F.marketingEmails
|
|
90
|
+
}
|
|
91
|
+
} });
|
|
92
|
+
if (e.error) throw e.error;
|
|
93
|
+
Y("saved"), await k(), setTimeout(() => Y("idle"), 3e3);
|
|
94
|
+
} catch {
|
|
95
|
+
Y("error"), setTimeout(() => Y("idle"), 5e3);
|
|
86
96
|
}
|
|
87
97
|
},
|
|
88
|
-
disabled:
|
|
89
|
-
"aria-disabled": !
|
|
90
|
-
className: t("inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-colors",
|
|
91
|
-
children: [
|
|
98
|
+
disabled: P || !T,
|
|
99
|
+
"aria-disabled": !T,
|
|
100
|
+
className: t("inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-colors", J === "saved" ? "bg-status-success-bg text-white" : J === "error" ? "bg-status-error-bg text-status-error-text" : "bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg/90", P && "opacity-50 cursor-not-allowed"),
|
|
101
|
+
children: [P ? /* @__PURE__ */ y(g, {
|
|
92
102
|
size: 16,
|
|
93
103
|
className: "animate-spin"
|
|
94
|
-
}) :
|
|
104
|
+
}) : y(J === "saved" ? m : J === "error" ? p : _, { size: 16 }), P ? C("devportal.savingButton", "Saving...") : J === "saved" ? C("devportal.savedButton", "Saved!") : J === "error" ? C("devportal.errorButton", "Error") : C("devportal.saveChangesButton", "Save Changes")]
|
|
95
105
|
}),
|
|
96
|
-
children: /* @__PURE__ */
|
|
106
|
+
children: /* @__PURE__ */ b("div", {
|
|
97
107
|
className: "flex flex-col gap-6",
|
|
98
|
-
children: [/* @__PURE__ */
|
|
108
|
+
children: [/* @__PURE__ */ b("div", {
|
|
99
109
|
className: "flex gap-3 rounded-lg border border-border-subtle bg-status-info-bg-subtle p-4 text-sm text-status-info-text",
|
|
100
|
-
children: [/* @__PURE__ */
|
|
110
|
+
children: [/* @__PURE__ */ y(h, {
|
|
101
111
|
size: 16,
|
|
102
112
|
className: "flex-shrink-0 mt-0.5"
|
|
103
|
-
}), /* @__PURE__ */
|
|
113
|
+
}), /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
|
|
104
114
|
className: "font-medium",
|
|
105
|
-
children:
|
|
106
|
-
}), /* @__PURE__ */
|
|
115
|
+
children: C("devportal.publisherProfilesWorkTitle", "How publisher profiles work")
|
|
116
|
+
}), /* @__PURE__ */ y("p", {
|
|
107
117
|
className: "mt-1 text-status-info-text",
|
|
108
|
-
children:
|
|
118
|
+
children: C("devportal.publisherProfilesWorkDesc", "When you publish your first app, a publisher profile is automatically created in the marketplace using your developer details. Keep this information up to date so users can trust and find your apps. Changes here are reflected when your next app is published.")
|
|
109
119
|
})] })]
|
|
110
|
-
}), /* @__PURE__ */
|
|
120
|
+
}), /* @__PURE__ */ b("div", {
|
|
111
121
|
className: "grid grid-cols-1 gap-6 lg:grid-cols-3",
|
|
112
|
-
children: [/* @__PURE__ */
|
|
122
|
+
children: [/* @__PURE__ */ b("div", {
|
|
113
123
|
className: "lg:col-span-2 space-y-6",
|
|
114
|
-
children: [/* @__PURE__ */
|
|
115
|
-
title:
|
|
116
|
-
description:
|
|
117
|
-
children: /* @__PURE__ */
|
|
124
|
+
children: [/* @__PURE__ */ y(o, {
|
|
125
|
+
title: C("devportal.publisherIdentityTitle", "Publisher Identity"),
|
|
126
|
+
description: C("devportal.publisherIdentityDesc", "Displayed on your marketplace listings"),
|
|
127
|
+
children: /* @__PURE__ */ b("div", {
|
|
118
128
|
className: "space-y-4",
|
|
119
129
|
children: [
|
|
120
|
-
/* @__PURE__ */
|
|
121
|
-
label:
|
|
122
|
-
value: M,
|
|
123
|
-
onChange: (e) => N(e.target.value),
|
|
124
|
-
placeholder: S("devportal.displayNamePlaceholder", "Your name or company (shown on all your apps)")
|
|
125
|
-
}),
|
|
126
|
-
/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
|
|
127
|
-
className: "text-sm font-medium text-text-primary",
|
|
128
|
-
children: S("devportal.bioLabel", "Bio")
|
|
129
|
-
}), /* @__PURE__ */ v("textarea", {
|
|
130
|
+
/* @__PURE__ */ y(s, {
|
|
131
|
+
label: C("devportal.displayNameLabel", "Display Name / Company"),
|
|
130
132
|
value: I,
|
|
131
133
|
onChange: (e) => L(e.target.value),
|
|
132
|
-
placeholder:
|
|
134
|
+
placeholder: C("devportal.displayNamePlaceholder", "Your name or company (shown on all your apps)")
|
|
135
|
+
}),
|
|
136
|
+
/* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("label", {
|
|
137
|
+
className: "text-sm font-medium text-text-primary",
|
|
138
|
+
children: C("devportal.bioLabel", "Bio")
|
|
139
|
+
}), /* @__PURE__ */ y("textarea", {
|
|
140
|
+
value: B,
|
|
141
|
+
onChange: (e) => V(e.target.value),
|
|
142
|
+
placeholder: C("devportal.bioPlaceholder", "A short description of you or your company shown on the marketplace..."),
|
|
133
143
|
rows: 3,
|
|
134
144
|
className: "mt-1 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm ring-offset-background placeholder:text-text-secondary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] resize-none"
|
|
135
145
|
})] }),
|
|
136
|
-
/* @__PURE__ */
|
|
137
|
-
label:
|
|
138
|
-
value:
|
|
139
|
-
onChange: (e) =>
|
|
140
|
-
placeholder:
|
|
146
|
+
/* @__PURE__ */ y(s, {
|
|
147
|
+
label: C("devportal.websiteLabel", "Website"),
|
|
148
|
+
value: R,
|
|
149
|
+
onChange: (e) => z(e.target.value),
|
|
150
|
+
placeholder: C("devportal.websitePlaceholder", "https://your-website.com")
|
|
141
151
|
})
|
|
142
152
|
]
|
|
143
153
|
})
|
|
144
|
-
}), /* @__PURE__ */
|
|
145
|
-
title:
|
|
146
|
-
description:
|
|
147
|
-
children: /* @__PURE__ */
|
|
154
|
+
}), /* @__PURE__ */ y(o, {
|
|
155
|
+
title: C("devportal.socialLinksTitle", "Social Links"),
|
|
156
|
+
description: C("devportal.socialLinksDesc", "Build trust with your developer community"),
|
|
157
|
+
children: /* @__PURE__ */ b("div", {
|
|
148
158
|
className: "space-y-4",
|
|
149
159
|
children: [
|
|
150
|
-
/* @__PURE__ */
|
|
151
|
-
label:
|
|
152
|
-
value: R,
|
|
153
|
-
onChange: (e) => z(e.target.value),
|
|
154
|
-
placeholder: S("devportal.githubUsernamePlaceholder", "your-github-username")
|
|
155
|
-
}),
|
|
156
|
-
/* @__PURE__ */ v(o, {
|
|
157
|
-
label: S("devportal.twitterUsernameLabel", "Twitter / X Username"),
|
|
158
|
-
value: B,
|
|
159
|
-
onChange: (e) => V(e.target.value),
|
|
160
|
-
placeholder: S("devportal.twitterUsernamePlaceholder", "your_twitter")
|
|
161
|
-
}),
|
|
162
|
-
/* @__PURE__ */ v(o, {
|
|
163
|
-
label: S("devportal.linkedinUrlLabel", "LinkedIn URL"),
|
|
160
|
+
/* @__PURE__ */ y(s, {
|
|
161
|
+
label: C("devportal.githubUsernameLabel", "GitHub Username"),
|
|
164
162
|
value: H,
|
|
165
163
|
onChange: (e) => U(e.target.value),
|
|
166
|
-
placeholder:
|
|
164
|
+
placeholder: C("devportal.githubUsernamePlaceholder", "your-github-username")
|
|
165
|
+
}),
|
|
166
|
+
/* @__PURE__ */ y(s, {
|
|
167
|
+
label: C("devportal.twitterUsernameLabel", "Twitter / X Username"),
|
|
168
|
+
value: W,
|
|
169
|
+
onChange: (e) => G(e.target.value),
|
|
170
|
+
placeholder: C("devportal.twitterUsernamePlaceholder", "your_twitter")
|
|
171
|
+
}),
|
|
172
|
+
/* @__PURE__ */ y(s, {
|
|
173
|
+
label: C("devportal.linkedinUrlLabel", "LinkedIn URL"),
|
|
174
|
+
value: K,
|
|
175
|
+
onChange: (e) => q(e.target.value),
|
|
176
|
+
placeholder: C("devportal.linkedinUrlPlaceholder", "https://linkedin.com/in/you")
|
|
167
177
|
})
|
|
168
178
|
]
|
|
169
179
|
})
|
|
170
180
|
})]
|
|
171
|
-
}), /* @__PURE__ */
|
|
181
|
+
}), /* @__PURE__ */ b("div", {
|
|
172
182
|
className: "space-y-6",
|
|
173
183
|
children: [
|
|
174
|
-
/* @__PURE__ */
|
|
175
|
-
title:
|
|
176
|
-
children: /* @__PURE__ */
|
|
184
|
+
/* @__PURE__ */ y(o, {
|
|
185
|
+
title: C("devportal.publisherStatusTitle", "Publisher Status"),
|
|
186
|
+
children: /* @__PURE__ */ b("div", {
|
|
177
187
|
className: "flex items-center gap-3",
|
|
178
|
-
children: [/* @__PURE__ */ v
|
|
188
|
+
children: [/* @__PURE__ */ y(v, { className: "h-8 w-8 text-primary" }), /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
|
|
179
189
|
className: "font-medium",
|
|
180
|
-
children:
|
|
181
|
-
}), /* @__PURE__ */
|
|
190
|
+
children: F?.isVerified ? C("devportal.verifiedPublisher", "Verified Publisher") : C("devportal.publisher", "Publisher")
|
|
191
|
+
}), /* @__PURE__ */ y("p", {
|
|
182
192
|
className: "text-xs text-text-secondary",
|
|
183
|
-
children:
|
|
193
|
+
children: F?.isVerified ? C("devportal.publisherIdentityVerified", "Your publisher identity is verified") : C("devportal.publishFirstAppMessage", "Publish your first app to appear in the marketplace")
|
|
184
194
|
})] })]
|
|
185
195
|
})
|
|
186
196
|
}),
|
|
187
|
-
/* @__PURE__ */
|
|
188
|
-
title:
|
|
189
|
-
children: /* @__PURE__ */
|
|
197
|
+
/* @__PURE__ */ y(o, {
|
|
198
|
+
title: C("devportal.profileCompletenessTitle", "Profile Completeness"),
|
|
199
|
+
children: /* @__PURE__ */ y("div", {
|
|
190
200
|
className: "space-y-2",
|
|
191
201
|
children: [
|
|
192
202
|
{
|
|
193
|
-
label:
|
|
194
|
-
ok: !!M
|
|
195
|
-
},
|
|
196
|
-
{
|
|
197
|
-
label: S("devportal.completenessBio", "Bio"),
|
|
203
|
+
label: C("devportal.completenessDisplayName", "Display name"),
|
|
198
204
|
ok: !!I
|
|
199
205
|
},
|
|
200
206
|
{
|
|
201
|
-
label:
|
|
202
|
-
ok: !!
|
|
207
|
+
label: C("devportal.completenessBio", "Bio"),
|
|
208
|
+
ok: !!B
|
|
203
209
|
},
|
|
204
210
|
{
|
|
205
|
-
label:
|
|
211
|
+
label: C("devportal.completenessWebsite", "Website"),
|
|
206
212
|
ok: !!R
|
|
207
213
|
},
|
|
208
214
|
{
|
|
209
|
-
label:
|
|
210
|
-
ok: !!
|
|
215
|
+
label: C("devportal.completenessGithub", "GitHub"),
|
|
216
|
+
ok: !!H
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
label: C("devportal.completenessSocialLinks", "Social links"),
|
|
220
|
+
ok: !!W || !!K
|
|
211
221
|
}
|
|
212
|
-
].map(({ label: e, ok: t }) => /* @__PURE__ */
|
|
222
|
+
].map(({ label: e, ok: t }) => /* @__PURE__ */ b("div", {
|
|
213
223
|
className: "flex items-center gap-2 text-sm",
|
|
214
|
-
children: [t ? /* @__PURE__ */
|
|
224
|
+
children: [t ? /* @__PURE__ */ y(m, {
|
|
215
225
|
size: 14,
|
|
216
226
|
className: "text-status-success-text"
|
|
217
|
-
}) : /* @__PURE__ */
|
|
227
|
+
}) : /* @__PURE__ */ y("div", { className: "h-3.5 w-3.5 rounded-full border-2 border-muted-foreground" }), /* @__PURE__ */ y("span", {
|
|
218
228
|
className: t ? "text-text-primary" : "text-text-secondary",
|
|
219
229
|
children: e
|
|
220
230
|
})]
|
|
221
231
|
}, e))
|
|
222
232
|
})
|
|
223
233
|
}),
|
|
224
|
-
/* @__PURE__ */
|
|
225
|
-
title:
|
|
226
|
-
children: /* @__PURE__ */
|
|
234
|
+
/* @__PURE__ */ y(o, {
|
|
235
|
+
title: C("devportal.marketplaceStatsTitle", "Marketplace Stats"),
|
|
236
|
+
children: /* @__PURE__ */ b("div", {
|
|
227
237
|
className: "space-y-3 text-sm",
|
|
228
238
|
children: [
|
|
229
|
-
/* @__PURE__ */
|
|
239
|
+
/* @__PURE__ */ b("div", {
|
|
230
240
|
className: "flex justify-between",
|
|
231
|
-
children: [/* @__PURE__ */
|
|
241
|
+
children: [/* @__PURE__ */ y("span", {
|
|
232
242
|
className: "text-text-secondary",
|
|
233
|
-
children:
|
|
234
|
-
}), /* @__PURE__ */
|
|
243
|
+
children: C("devportal.publishedAppsLabel", "Published apps")
|
|
244
|
+
}), /* @__PURE__ */ y("span", {
|
|
235
245
|
className: "font-semibold",
|
|
236
|
-
children:
|
|
246
|
+
children: F?.applicationCount ?? 0
|
|
237
247
|
})]
|
|
238
248
|
}),
|
|
239
|
-
/* @__PURE__ */
|
|
249
|
+
/* @__PURE__ */ b("div", {
|
|
240
250
|
className: "flex justify-between",
|
|
241
|
-
children: [/* @__PURE__ */
|
|
251
|
+
children: [/* @__PURE__ */ y("span", {
|
|
242
252
|
className: "text-text-secondary",
|
|
243
|
-
children:
|
|
244
|
-
}), /* @__PURE__ */
|
|
253
|
+
children: C("devportal.totalInstallsLabel", "Total installs")
|
|
254
|
+
}), /* @__PURE__ */ y("span", {
|
|
245
255
|
className: "font-semibold",
|
|
246
|
-
children:
|
|
256
|
+
children: F?.totalInstalls ?? 0
|
|
247
257
|
})]
|
|
248
258
|
}),
|
|
249
|
-
/* @__PURE__ */
|
|
259
|
+
/* @__PURE__ */ b("div", {
|
|
250
260
|
className: "flex justify-between",
|
|
251
|
-
children: [/* @__PURE__ */
|
|
261
|
+
children: [/* @__PURE__ */ y("span", {
|
|
252
262
|
className: "text-text-secondary",
|
|
253
|
-
children:
|
|
254
|
-
}), /* @__PURE__ */
|
|
263
|
+
children: C("devportal.avgRatingLabel", "Avg rating")
|
|
264
|
+
}), /* @__PURE__ */ y("span", {
|
|
255
265
|
className: "font-semibold",
|
|
256
|
-
children:
|
|
266
|
+
children: F?.averageRating ? F.averageRating.toFixed(1) : "—"
|
|
257
267
|
})]
|
|
258
268
|
})
|
|
259
269
|
]
|
|
@@ -267,6 +277,6 @@ var x = () => {
|
|
|
267
277
|
});
|
|
268
278
|
};
|
|
269
279
|
//#endregion
|
|
270
|
-
export {
|
|
280
|
+
export { S as PublisherProfilePage };
|
|
271
281
|
|
|
272
282
|
//# sourceMappingURL=PublisherProfilePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PublisherProfilePage.js","names":[],"sources":["../../../src/devportal/pages/PublisherProfilePage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useState, useEffect } from \"react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n Store,\n Save,\n CheckCircle2,\n AlertCircle,\n Loader2,\n Info,\n} from \"lucide-react\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { InputField } from \"../components/FormField\";\nimport { cn } from \"../utils/cn\";\nimport { PermissionGuard } from \"../components\";\nimport { DEVPORTAL_PERMISSIONS } from \"../constants/permissions\";\nimport { useDevportalPermission } from \"../hooks/usePermission\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport {\n useGetMyDeveloperProfileQuery,\n useUpdateDeveloperProfileMutation,\n} from \"../hooks/useGraphQL\";\n\n/**\n * Publisher Profile Page\n *\n * Lets developers enrich their store publisher presence.\n * The publisher profile in global-store-svc is auto-created when an app is\n * first published. This page surfaces the underlying developer profile fields\n * that feed into that publisher identity so developers can keep them current.\n */\nexport const PublisherProfilePage: FC = () => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const { currentUser } = useDevportal();\n const { allowed: canSave } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.PROFILE_UPDATE,\n );\n const { data, loading, error, refetch } = useGetMyDeveloperProfileQuery({\n fetchPolicy: \"cache-and-network\",\n });\n\n const [updateProfile, { loading: saving }] =\n useUpdateDeveloperProfileMutation();\n\n const profile = data?.myDeveloperProfile;\n\n // Form state — publisher-relevant fields\n const [companyName, setCompanyName] = useState(\"\");\n const [website, setWebsite] = useState(\"\");\n const [bio, setBio] = useState(\"\");\n const [githubUsername, setGithubUsername] = useState(\"\");\n const [twitterUsername, setTwitterUsername] = useState(\"\");\n const [linkedinUrl, setLinkedinUrl] = useState(\"\");\n\n const [saveStatus, setSaveStatus] = useState<\n \"idle\" | \"saving\" | \"saved\" | \"error\"\n >(\"idle\");\n\n useEffect(() => {\n if (profile) {\n setCompanyName(profile.companyName ?? \"\");\n setWebsite(profile.website ?? \"\");\n setBio(profile.bio ?? \"\");\n setGithubUsername(profile.githubUsername ?? \"\");\n setTwitterUsername(profile.twitterUsername ?? \"\");\n setLinkedinUrl(profile.linkedinUrl ?? \"\");\n } else if (!loading && currentUser) {\n // No profile yet — pre-fill display name from account\n const fullName = [currentUser.firstName, currentUser.lastName]\n .filter(Boolean)\n .join(\" \");\n if (fullName) setCompanyName(fullName);\n }\n }, [profile, loading, currentUser]);\n\n const handleSave = async () => {\n const userId = profile?.userId ?? currentUser?.id;\n if (!userId) return;\n setSaveStatus(\"saving\");\n try {\n const result = await updateProfile({\n variables: {\n userId,\n input: {\n companyName: companyName || null,\n website: website || null,\n bio: bio || null,\n githubUsername: githubUsername || null,\n twitterUsername: twitterUsername || null,\n linkedinUrl: linkedinUrl || null,\n // preserve existing notification prefs\n emailNotifications: profile?.emailNotifications,\n marketingEmails: profile?.marketingEmails,\n },\n },\n });\n if (result.error) {\n throw result.error;\n }\n setSaveStatus(\"saved\");\n await refetch();\n setTimeout(() => setSaveStatus(\"idle\"), 3000);\n } catch {\n setSaveStatus(\"error\");\n setTimeout(() => setSaveStatus(\"idle\"), 5000);\n }\n };\n\n if (loading && !profile) {\n return (\n <PageLayout\n title={tr(\"devportal.publisherProfileTitle\", \"Publisher Profile\")}\n description={tr(\n \"devportal.loadingPublisherProfile\",\n \"Loading your publisher profile...\",\n )}\n >\n <div className=\"flex items-center justify-center py-20\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n </div>\n </PageLayout>\n );\n }\n\n if (error && !profile) {\n return (\n <PageLayout\n title={tr(\"devportal.publisherProfileTitle\", \"Publisher Profile\")}\n description={tr(\n \"devportal.manageStorePublisherPresence\",\n \"Manage your store publisher presence\",\n )}\n >\n <div className=\"flex flex-col items-center justify-center gap-4 py-20\">\n <AlertCircle className=\"h-12 w-12 text-status-error-text\" />\n <p className=\"text-text-secondary\">\n {tr(\"devportal.failedToLoadProfile\", \"Failed to load profile\")}\n </p>\n <button\n onClick={() => refetch()}\n className=\"rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n {tr(\"devportal.retryButton\", \"Retry\")}\n </button>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={tr(\"devportal.publisherProfileTitle\", \"Publisher Profile\")}\n description={tr(\n \"devportal.manageMarketplaceAppearance\",\n \"Manage how you appear to users in the marketplace\",\n )}\n purpose={tr(\n \"devportal.publisherProfilePurpose\",\n \"This is your public face in the marketplace — the name, logo, bio, and links users see before installing your apps. A complete, trustworthy profile makes shoppers more likely to install and is required before some apps can be published.\",\n )}\n actions={\n <button\n onClick={handleSave}\n disabled={saving || !canSave}\n aria-disabled={!canSave}\n className={cn(\n \"inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-colors\",\n saveStatus === \"saved\"\n ? \"bg-status-success-bg text-white\"\n : saveStatus === \"error\"\n ? \"bg-status-error-bg text-status-error-text\"\n : \"bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg/90\",\n saving && \"opacity-50 cursor-not-allowed\",\n )}\n >\n {saving ? (\n <Loader2 size={16} className=\"animate-spin\" />\n ) : saveStatus === \"saved\" ? (\n <CheckCircle2 size={16} />\n ) : saveStatus === \"error\" ? (\n <AlertCircle size={16} />\n ) : (\n <Save size={16} />\n )}\n {saving\n ? tr(\"devportal.savingButton\", \"Saving...\")\n : saveStatus === \"saved\"\n ? tr(\"devportal.savedButton\", \"Saved!\")\n : saveStatus === \"error\"\n ? tr(\"devportal.errorButton\", \"Error\")\n : tr(\"devportal.saveChangesButton\", \"Save Changes\")}\n </button>\n }\n >\n <div className=\"flex flex-col gap-6\">\n <div className=\"flex gap-3 rounded-lg border border-border-subtle bg-status-info-bg-subtle p-4 text-sm text-status-info-text\">\n <Info size={16} className=\"flex-shrink-0 mt-0.5\" />\n <div>\n <p className=\"font-medium\">\n {tr(\n \"devportal.publisherProfilesWorkTitle\",\n \"How publisher profiles work\",\n )}\n </p>\n <p className=\"mt-1 text-status-info-text\">\n {tr(\n \"devportal.publisherProfilesWorkDesc\",\n \"When you publish your first app, a publisher profile is automatically created in the marketplace using your developer details. Keep this information up to date so users can trust and find your apps. Changes here are reflected when your next app is published.\",\n )}\n </p>\n </div>\n </div>\n\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-3\">\n {/* Main form */}\n <div className=\"lg:col-span-2 space-y-6\">\n {/* Publisher identity */}\n <PageSection\n title={tr(\n \"devportal.publisherIdentityTitle\",\n \"Publisher Identity\",\n )}\n description={tr(\n \"devportal.publisherIdentityDesc\",\n \"Displayed on your marketplace listings\",\n )}\n >\n <div className=\"space-y-4\">\n <InputField\n label={tr(\n \"devportal.displayNameLabel\",\n \"Display Name / Company\",\n )}\n value={companyName}\n onChange={(e) => setCompanyName(e.target.value)}\n placeholder={tr(\n \"devportal.displayNamePlaceholder\",\n \"Your name or company (shown on all your apps)\",\n )}\n />\n <div>\n <label className=\"text-sm font-medium text-text-primary\">\n {tr(\"devportal.bioLabel\", \"Bio\")}\n </label>\n <textarea\n value={bio}\n onChange={(e) => setBio(e.target.value)}\n placeholder={tr(\n \"devportal.bioPlaceholder\",\n \"A short description of you or your company shown on the marketplace...\",\n )}\n rows={3}\n className=\"mt-1 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm ring-offset-background placeholder:text-text-secondary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] resize-none\"\n />\n </div>\n <InputField\n label={tr(\"devportal.websiteLabel\", \"Website\")}\n value={website}\n onChange={(e) => setWebsite(e.target.value)}\n placeholder={tr(\n \"devportal.websitePlaceholder\",\n \"https://your-website.com\",\n )}\n />\n </div>\n </PageSection>\n\n {/* Social links */}\n <PageSection\n title={tr(\"devportal.socialLinksTitle\", \"Social Links\")}\n description={tr(\n \"devportal.socialLinksDesc\",\n \"Build trust with your developer community\",\n )}\n >\n <div className=\"space-y-4\">\n <InputField\n label={tr(\n \"devportal.githubUsernameLabel\",\n \"GitHub Username\",\n )}\n value={githubUsername}\n onChange={(e) => setGithubUsername(e.target.value)}\n placeholder={tr(\n \"devportal.githubUsernamePlaceholder\",\n \"your-github-username\",\n )}\n />\n <InputField\n label={tr(\n \"devportal.twitterUsernameLabel\",\n \"Twitter / X Username\",\n )}\n value={twitterUsername}\n onChange={(e) => setTwitterUsername(e.target.value)}\n placeholder={tr(\n \"devportal.twitterUsernamePlaceholder\",\n \"your_twitter\",\n )}\n />\n <InputField\n label={tr(\"devportal.linkedinUrlLabel\", \"LinkedIn URL\")}\n value={linkedinUrl}\n onChange={(e) => setLinkedinUrl(e.target.value)}\n placeholder={tr(\n \"devportal.linkedinUrlPlaceholder\",\n \"https://linkedin.com/in/you\",\n )}\n />\n </div>\n </PageSection>\n </div>\n\n {/* Sidebar */}\n <div className=\"space-y-6\">\n {/* Publisher status */}\n <PageSection\n title={tr(\"devportal.publisherStatusTitle\", \"Publisher Status\")}\n >\n <div className=\"flex items-center gap-3\">\n <Store className=\"h-8 w-8 text-primary\" />\n <div>\n <p className=\"font-medium\">\n {profile?.isVerified\n ? tr(\n \"devportal.verifiedPublisher\",\n \"Verified Publisher\",\n )\n : tr(\"devportal.publisher\", \"Publisher\")}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {profile?.isVerified\n ? tr(\n \"devportal.publisherIdentityVerified\",\n \"Your publisher identity is verified\",\n )\n : tr(\n \"devportal.publishFirstAppMessage\",\n \"Publish your first app to appear in the marketplace\",\n )}\n </p>\n </div>\n </div>\n </PageSection>\n\n {/* Profile completeness */}\n <PageSection\n title={tr(\n \"devportal.profileCompletenessTitle\",\n \"Profile Completeness\",\n )}\n >\n <div className=\"space-y-2\">\n {[\n {\n label: tr(\n \"devportal.completenessDisplayName\",\n \"Display name\",\n ),\n ok: !!companyName,\n },\n {\n label: tr(\"devportal.completenessBio\", \"Bio\"),\n ok: !!bio,\n },\n {\n label: tr(\"devportal.completenessWebsite\", \"Website\"),\n ok: !!website,\n },\n {\n label: tr(\"devportal.completenessGithub\", \"GitHub\"),\n ok: !!githubUsername,\n },\n {\n label: tr(\n \"devportal.completenessSocialLinks\",\n \"Social links\",\n ),\n ok: !!twitterUsername || !!linkedinUrl,\n },\n ].map(({ label, ok }) => (\n <div\n key={label}\n className=\"flex items-center gap-2 text-sm\"\n >\n {ok ? (\n <CheckCircle2\n size={14}\n className=\"text-status-success-text\"\n />\n ) : (\n <div className=\"h-3.5 w-3.5 rounded-full border-2 border-muted-foreground\" />\n )}\n <span\n className={\n ok ? \"text-text-primary\" : \"text-text-secondary\"\n }\n >\n {label}\n </span>\n </div>\n ))}\n </div>\n </PageSection>\n\n {/* Stats */}\n <PageSection\n title={tr(\n \"devportal.marketplaceStatsTitle\",\n \"Marketplace Stats\",\n )}\n >\n <div className=\"space-y-3 text-sm\">\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">\n {tr(\"devportal.publishedAppsLabel\", \"Published apps\")}\n </span>\n <span className=\"font-semibold\">\n {profile?.applicationCount ?? 0}\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">\n {tr(\"devportal.totalInstallsLabel\", \"Total installs\")}\n </span>\n <span className=\"font-semibold\">\n {profile?.totalInstalls ?? 0}\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">\n {tr(\"devportal.avgRatingLabel\", \"Avg rating\")}\n </span>\n <span className=\"font-semibold\">\n {profile?.averageRating\n ? profile.averageRating.toFixed(1)\n : \"—\"}\n </span>\n </div>\n </div>\n </PageSection>\n </div>\n </div>\n </div>\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PublisherProfilePage.js","names":[],"sources":["../../../src/devportal/pages/PublisherProfilePage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useState, useEffect } from \"react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n Store,\n Save,\n CheckCircle2,\n AlertCircle,\n Loader2,\n Info,\n} from \"lucide-react\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { InputField } from \"../components/FormField\";\nimport { cn } from \"../utils/cn\";\nimport { PermissionGuard } from \"../components\";\nimport { DEVPORTAL_PERMISSIONS } from \"../constants/permissions\";\nimport { useDevportalPermission } from \"../hooks/usePermission\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport {\n useCreateDeveloperProfileMutation,\n useGetMyDeveloperProfileQuery,\n useUpdateDeveloperProfileMutation,\n} from \"../hooks/useGraphQL\";\n\n/**\n * Publisher Profile Page\n *\n * Lets developers enrich their store publisher presence.\n * The publisher profile in global-store-svc is auto-created when an app is\n * first published. This page surfaces the underlying developer profile fields\n * that feed into that publisher identity so developers can keep them current.\n */\nexport const PublisherProfilePage: FC = () => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const { currentUser } = useDevportal();\n const { allowed: canSave } = useDevportalPermission(\n DEVPORTAL_PERMISSIONS.PROFILE_UPDATE,\n );\n const { data, loading, error, refetch } = useGetMyDeveloperProfileQuery({\n fetchPolicy: \"cache-and-network\",\n });\n\n const [updateProfile, { loading: updating }] =\n useUpdateDeveloperProfileMutation();\n // A developer who arrives from the public registration journey has no\n // profile yet; updateDeveloperProfile refuses that case, so the first save\n // creates the profile instead (BOFF-10636).\n const [createProfile, { loading: creating }] =\n useCreateDeveloperProfileMutation();\n const saving = updating || creating;\n\n const profile = data?.myDeveloperProfile;\n\n // Form state — publisher-relevant fields\n const [companyName, setCompanyName] = useState(\"\");\n const [website, setWebsite] = useState(\"\");\n const [bio, setBio] = useState(\"\");\n const [githubUsername, setGithubUsername] = useState(\"\");\n const [twitterUsername, setTwitterUsername] = useState(\"\");\n const [linkedinUrl, setLinkedinUrl] = useState(\"\");\n\n const [saveStatus, setSaveStatus] = useState<\n \"idle\" | \"saving\" | \"saved\" | \"error\"\n >(\"idle\");\n\n useEffect(() => {\n if (profile) {\n setCompanyName(profile.companyName ?? \"\");\n setWebsite(profile.website ?? \"\");\n setBio(profile.bio ?? \"\");\n setGithubUsername(profile.githubUsername ?? \"\");\n setTwitterUsername(profile.twitterUsername ?? \"\");\n setLinkedinUrl(profile.linkedinUrl ?? \"\");\n } else if (!loading && currentUser) {\n // No profile yet — pre-fill display name from account\n const fullName = [currentUser.firstName, currentUser.lastName]\n .filter(Boolean)\n .join(\" \");\n if (fullName) setCompanyName(fullName);\n }\n }, [profile, loading, currentUser]);\n\n const handleSave = async () => {\n setSaveStatus(\"saving\");\n try {\n if (!profile) {\n const created = await createProfile({\n variables: {\n input: {\n companyName: companyName || undefined,\n website: website || undefined,\n bio: bio || undefined,\n githubUsername: githubUsername || undefined,\n twitterUsername: twitterUsername || undefined,\n linkedinUrl: linkedinUrl || undefined,\n },\n },\n });\n if (created.error) {\n throw created.error;\n }\n setSaveStatus(\"saved\");\n await refetch();\n setTimeout(() => setSaveStatus(\"idle\"), 3000);\n return;\n }\n const result = await updateProfile({\n variables: {\n userId: profile.userId,\n input: {\n companyName: companyName || null,\n website: website || null,\n bio: bio || null,\n githubUsername: githubUsername || null,\n twitterUsername: twitterUsername || null,\n linkedinUrl: linkedinUrl || null,\n // preserve existing notification prefs\n emailNotifications: profile.emailNotifications,\n marketingEmails: profile.marketingEmails,\n },\n },\n });\n if (result.error) {\n throw result.error;\n }\n setSaveStatus(\"saved\");\n await refetch();\n setTimeout(() => setSaveStatus(\"idle\"), 3000);\n } catch {\n setSaveStatus(\"error\");\n setTimeout(() => setSaveStatus(\"idle\"), 5000);\n }\n };\n\n if (loading && !profile) {\n return (\n <PageLayout\n title={tr(\"devportal.publisherProfileTitle\", \"Publisher Profile\")}\n description={tr(\n \"devportal.loadingPublisherProfile\",\n \"Loading your publisher profile...\",\n )}\n >\n <div className=\"flex items-center justify-center py-20\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n </div>\n </PageLayout>\n );\n }\n\n if (error && !profile) {\n return (\n <PageLayout\n title={tr(\"devportal.publisherProfileTitle\", \"Publisher Profile\")}\n description={tr(\n \"devportal.manageStorePublisherPresence\",\n \"Manage your store publisher presence\",\n )}\n >\n <div className=\"flex flex-col items-center justify-center gap-4 py-20\">\n <AlertCircle className=\"h-12 w-12 text-status-error-text\" />\n <p className=\"text-text-secondary\">\n {tr(\"devportal.failedToLoadProfile\", \"Failed to load profile\")}\n </p>\n <button\n onClick={() => refetch()}\n className=\"rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n {tr(\"devportal.retryButton\", \"Retry\")}\n </button>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={tr(\"devportal.publisherProfileTitle\", \"Publisher Profile\")}\n description={tr(\n \"devportal.manageMarketplaceAppearance\",\n \"Manage how you appear to users in the marketplace\",\n )}\n purpose={tr(\n \"devportal.publisherProfilePurpose\",\n \"This is your public face in the marketplace — the name, logo, bio, and links users see before installing your apps. A complete, trustworthy profile makes shoppers more likely to install and is required before some apps can be published.\",\n )}\n actions={\n <button\n onClick={handleSave}\n disabled={saving || !canSave}\n aria-disabled={!canSave}\n className={cn(\n \"inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-colors\",\n saveStatus === \"saved\"\n ? \"bg-status-success-bg text-white\"\n : saveStatus === \"error\"\n ? \"bg-status-error-bg text-status-error-text\"\n : \"bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg/90\",\n saving && \"opacity-50 cursor-not-allowed\",\n )}\n >\n {saving ? (\n <Loader2 size={16} className=\"animate-spin\" />\n ) : saveStatus === \"saved\" ? (\n <CheckCircle2 size={16} />\n ) : saveStatus === \"error\" ? (\n <AlertCircle size={16} />\n ) : (\n <Save size={16} />\n )}\n {saving\n ? tr(\"devportal.savingButton\", \"Saving...\")\n : saveStatus === \"saved\"\n ? tr(\"devportal.savedButton\", \"Saved!\")\n : saveStatus === \"error\"\n ? tr(\"devportal.errorButton\", \"Error\")\n : tr(\"devportal.saveChangesButton\", \"Save Changes\")}\n </button>\n }\n >\n <div className=\"flex flex-col gap-6\">\n <div className=\"flex gap-3 rounded-lg border border-border-subtle bg-status-info-bg-subtle p-4 text-sm text-status-info-text\">\n <Info size={16} className=\"flex-shrink-0 mt-0.5\" />\n <div>\n <p className=\"font-medium\">\n {tr(\n \"devportal.publisherProfilesWorkTitle\",\n \"How publisher profiles work\",\n )}\n </p>\n <p className=\"mt-1 text-status-info-text\">\n {tr(\n \"devportal.publisherProfilesWorkDesc\",\n \"When you publish your first app, a publisher profile is automatically created in the marketplace using your developer details. Keep this information up to date so users can trust and find your apps. Changes here are reflected when your next app is published.\",\n )}\n </p>\n </div>\n </div>\n\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-3\">\n {/* Main form */}\n <div className=\"lg:col-span-2 space-y-6\">\n {/* Publisher identity */}\n <PageSection\n title={tr(\n \"devportal.publisherIdentityTitle\",\n \"Publisher Identity\",\n )}\n description={tr(\n \"devportal.publisherIdentityDesc\",\n \"Displayed on your marketplace listings\",\n )}\n >\n <div className=\"space-y-4\">\n <InputField\n label={tr(\n \"devportal.displayNameLabel\",\n \"Display Name / Company\",\n )}\n value={companyName}\n onChange={(e) => setCompanyName(e.target.value)}\n placeholder={tr(\n \"devportal.displayNamePlaceholder\",\n \"Your name or company (shown on all your apps)\",\n )}\n />\n <div>\n <label className=\"text-sm font-medium text-text-primary\">\n {tr(\"devportal.bioLabel\", \"Bio\")}\n </label>\n <textarea\n value={bio}\n onChange={(e) => setBio(e.target.value)}\n placeholder={tr(\n \"devportal.bioPlaceholder\",\n \"A short description of you or your company shown on the marketplace...\",\n )}\n rows={3}\n className=\"mt-1 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm ring-offset-background placeholder:text-text-secondary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] resize-none\"\n />\n </div>\n <InputField\n label={tr(\"devportal.websiteLabel\", \"Website\")}\n value={website}\n onChange={(e) => setWebsite(e.target.value)}\n placeholder={tr(\n \"devportal.websitePlaceholder\",\n \"https://your-website.com\",\n )}\n />\n </div>\n </PageSection>\n\n {/* Social links */}\n <PageSection\n title={tr(\"devportal.socialLinksTitle\", \"Social Links\")}\n description={tr(\n \"devportal.socialLinksDesc\",\n \"Build trust with your developer community\",\n )}\n >\n <div className=\"space-y-4\">\n <InputField\n label={tr(\n \"devportal.githubUsernameLabel\",\n \"GitHub Username\",\n )}\n value={githubUsername}\n onChange={(e) => setGithubUsername(e.target.value)}\n placeholder={tr(\n \"devportal.githubUsernamePlaceholder\",\n \"your-github-username\",\n )}\n />\n <InputField\n label={tr(\n \"devportal.twitterUsernameLabel\",\n \"Twitter / X Username\",\n )}\n value={twitterUsername}\n onChange={(e) => setTwitterUsername(e.target.value)}\n placeholder={tr(\n \"devportal.twitterUsernamePlaceholder\",\n \"your_twitter\",\n )}\n />\n <InputField\n label={tr(\"devportal.linkedinUrlLabel\", \"LinkedIn URL\")}\n value={linkedinUrl}\n onChange={(e) => setLinkedinUrl(e.target.value)}\n placeholder={tr(\n \"devportal.linkedinUrlPlaceholder\",\n \"https://linkedin.com/in/you\",\n )}\n />\n </div>\n </PageSection>\n </div>\n\n {/* Sidebar */}\n <div className=\"space-y-6\">\n {/* Publisher status */}\n <PageSection\n title={tr(\"devportal.publisherStatusTitle\", \"Publisher Status\")}\n >\n <div className=\"flex items-center gap-3\">\n <Store className=\"h-8 w-8 text-primary\" />\n <div>\n <p className=\"font-medium\">\n {profile?.isVerified\n ? tr(\n \"devportal.verifiedPublisher\",\n \"Verified Publisher\",\n )\n : tr(\"devportal.publisher\", \"Publisher\")}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {profile?.isVerified\n ? tr(\n \"devportal.publisherIdentityVerified\",\n \"Your publisher identity is verified\",\n )\n : tr(\n \"devportal.publishFirstAppMessage\",\n \"Publish your first app to appear in the marketplace\",\n )}\n </p>\n </div>\n </div>\n </PageSection>\n\n {/* Profile completeness */}\n <PageSection\n title={tr(\n \"devportal.profileCompletenessTitle\",\n \"Profile Completeness\",\n )}\n >\n <div className=\"space-y-2\">\n {[\n {\n label: tr(\n \"devportal.completenessDisplayName\",\n \"Display name\",\n ),\n ok: !!companyName,\n },\n {\n label: tr(\"devportal.completenessBio\", \"Bio\"),\n ok: !!bio,\n },\n {\n label: tr(\"devportal.completenessWebsite\", \"Website\"),\n ok: !!website,\n },\n {\n label: tr(\"devportal.completenessGithub\", \"GitHub\"),\n ok: !!githubUsername,\n },\n {\n label: tr(\n \"devportal.completenessSocialLinks\",\n \"Social links\",\n ),\n ok: !!twitterUsername || !!linkedinUrl,\n },\n ].map(({ label, ok }) => (\n <div\n key={label}\n className=\"flex items-center gap-2 text-sm\"\n >\n {ok ? (\n <CheckCircle2\n size={14}\n className=\"text-status-success-text\"\n />\n ) : (\n <div className=\"h-3.5 w-3.5 rounded-full border-2 border-muted-foreground\" />\n )}\n <span\n className={\n ok ? \"text-text-primary\" : \"text-text-secondary\"\n }\n >\n {label}\n </span>\n </div>\n ))}\n </div>\n </PageSection>\n\n {/* Stats */}\n <PageSection\n title={tr(\n \"devportal.marketplaceStatsTitle\",\n \"Marketplace Stats\",\n )}\n >\n <div className=\"space-y-3 text-sm\">\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">\n {tr(\"devportal.publishedAppsLabel\", \"Published apps\")}\n </span>\n <span className=\"font-semibold\">\n {profile?.applicationCount ?? 0}\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">\n {tr(\"devportal.totalInstallsLabel\", \"Total installs\")}\n </span>\n <span className=\"font-semibold\">\n {profile?.totalInstalls ?? 0}\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">\n {tr(\"devportal.avgRatingLabel\", \"Avg rating\")}\n </span>\n <span className=\"font-semibold\">\n {profile?.averageRating\n ? profile.averageRating.toFixed(1)\n : \"—\"}\n </span>\n </div>\n </div>\n </PageSection>\n </div>\n </div>\n </div>\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
|
|
@@ -13,8 +13,8 @@ var E = "https://docs.burdenoff.com/developers", D = {
|
|
|
13
13
|
name: "SDKs",
|
|
14
14
|
description: "Official client libraries for building on the Burdenoff platform. See the SDKs documentation for supported languages and installation.",
|
|
15
15
|
icon: /* @__PURE__ */ S(d, { size: 24 }),
|
|
16
|
-
url: `${E}/
|
|
17
|
-
installCommand: "npm install @burdenoff/sdk
|
|
16
|
+
url: `${E}/node-sdk`,
|
|
17
|
+
installCommand: "npm install @burdenoff/workspaces-sdk"
|
|
18
18
|
}, O = [
|
|
19
19
|
{
|
|
20
20
|
id: "graphql-api",
|