@burdenoff/microfe-devportal 2026.611.2 → 2026.616.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/components/SectionNav.js +105 -41
- package/dist/devportal/components/SectionNav.js.map +1 -1
- package/dist/devportal/hooks/useGraphQL.js +1 -1
- package/dist/devportal/pages/AdminReviewPage.js +36 -36
- package/dist/devportal/pages/AnalyticsDashboardPage.js +150 -150
- package/dist/devportal/pages/AnalyticsDashboardPage.js.map +1 -1
- package/dist/devportal/pages/ApiKeysPage.js +184 -172
- package/dist/devportal/pages/ApiKeysPage.js.map +1 -1
- package/dist/devportal/pages/AppLogsPage.js +9 -9
- package/dist/devportal/pages/ApplicationDetailPage.js +414 -414
- package/dist/devportal/pages/ApplicationDetailPage.js.map +1 -1
- package/dist/devportal/pages/ApplicationVersionsPage.js +44 -44
- package/dist/devportal/pages/ApplicationVersionsPage.js.map +1 -1
- package/dist/devportal/pages/ApplicationsPage.js +118 -118
- package/dist/devportal/pages/ApplicationsPage.js.map +1 -1
- package/dist/devportal/pages/CreateApiKeyPage.js +20 -20
- package/dist/devportal/pages/CreateApplicationPage.js +46 -66
- package/dist/devportal/pages/CreateApplicationPage.js.map +1 -1
- package/dist/devportal/pages/CreateOAuthClientPage.js +20 -20
- package/dist/devportal/pages/CreateOrganizationPage.js +125 -442
- package/dist/devportal/pages/CreateOrganizationPage.js.map +1 -1
- package/dist/devportal/pages/CreateWebhookPage.js +25 -25
- package/dist/devportal/pages/DashboardPage.js +160 -145
- package/dist/devportal/pages/DashboardPage.js.map +1 -1
- package/dist/devportal/pages/DelegationsPage.js +22 -22
- package/dist/devportal/pages/EditApplicationPage.js +297 -317
- package/dist/devportal/pages/EditApplicationPage.js.map +1 -1
- package/dist/devportal/pages/ListingPreviewPage.js +9 -9
- package/dist/devportal/pages/OAuthClientDetailPage.js +17 -17
- package/dist/devportal/pages/OAuthClientsPage.js +16 -16
- package/dist/devportal/pages/OrganizationDetailPage.js +78 -78
- package/dist/devportal/pages/OrganizationMembersPage.js +260 -260
- package/dist/devportal/pages/OrganizationMembersPage.js.map +1 -1
- package/dist/devportal/pages/OrganizationsPage.js +18 -18
- package/dist/devportal/pages/PublishPage.js +16 -16
- package/dist/devportal/pages/PublisherProfilePage.js +156 -146
- package/dist/devportal/pages/PublisherProfilePage.js.map +1 -1
- package/dist/devportal/pages/RevenueDashboardPage.js +512 -362
- package/dist/devportal/pages/RevenueDashboardPage.js.map +1 -1
- package/dist/devportal/pages/SettingsPage.js +17 -17
- package/dist/devportal/pages/SetupPage.js +99 -99
- package/dist/devportal/pages/SetupPage.js.map +1 -1
- package/dist/devportal/pages/WebhookDetailPage.js +143 -143
- package/dist/devportal/pages/WebhookDetailPage.js.map +1 -1
- package/dist/devportal/pages/WebhooksPage.js +140 -140
- package/dist/devportal/pages/WebhooksPage.js.map +1 -1
- package/dist/devportal/providers/DevportalProvider.js +46 -33
- package/dist/devportal/providers/DevportalProvider.js.map +1 -1
- package/dist/generated/global-operations.js +69 -55
- package/dist/generated/global-operations.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,246 +1,256 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { useGetMyDeveloperProfileQuery as i, useUpdateDeveloperProfileMutation as a } from "../../generated/global-operations.js";
|
|
5
|
-
import { PermissionGuard as o } from "../components/PermissionGuard.js";
|
|
6
|
-
import "../components/index.js";
|
|
7
|
-
import { DEVPORTAL_PERMISSIONS as s } from "../constants/permissions.js";
|
|
1
|
+
import { useDevportal as e } from "../providers/DevportalProvider.js";
|
|
2
|
+
import { cn as t } from "../utils/cn.js";
|
|
3
|
+
import { useGetMyDeveloperProfileQuery as n, useUpdateDeveloperProfileMutation as r } from "../../generated/global-operations.js";
|
|
8
4
|
import "../hooks/useGraphQL.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import
|
|
13
|
-
import {
|
|
5
|
+
import { PageLayout as i, PageSection as a } from "../components/PageLayout.js";
|
|
6
|
+
import { InputField as o } from "../components/FormField.js";
|
|
7
|
+
import { PermissionGuard as s } from "../components/PermissionGuard.js";
|
|
8
|
+
import "../components/index.js";
|
|
9
|
+
import { DEVPORTAL_PERMISSIONS as c } from "../constants/permissions.js";
|
|
10
|
+
import { useDevportalPermission as l } from "../hooks/usePermission.js";
|
|
11
|
+
import { useEffect as u, useState as d } from "react";
|
|
12
|
+
import { useI18n as f } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
13
|
+
import { AlertCircle as p, CheckCircle2 as m, Info as h, Loader2 as g, Save as _, Store as v } from "lucide-react";
|
|
14
|
+
import { jsx as y, jsxs as b } from "react/jsx-runtime";
|
|
14
15
|
//#region src/devportal/pages/PublisherProfilePage.tsx
|
|
15
|
-
var
|
|
16
|
-
let { t:
|
|
17
|
-
let n =
|
|
16
|
+
var x = () => {
|
|
17
|
+
let { t: x } = f(), S = (e, t) => {
|
|
18
|
+
let n = x(e);
|
|
18
19
|
return n === e ? t : n;
|
|
19
|
-
}, { allowed:
|
|
20
|
-
return
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
}, { currentUser: C } = e(), { allowed: w } = l(c.PROFILE_UPDATE), { data: T, loading: E, error: D, refetch: O } = n({ fetchPolicy: "cache-and-network" }), [k, { loading: A }] = r(), j = T?.myDeveloperProfile, [M, N] = d(""), [P, F] = d(""), [I, L] = d(""), [R, z] = d(""), [B, V] = d(""), [H, U] = d(""), [W, G] = d("idle");
|
|
21
|
+
return u(() => {
|
|
22
|
+
if (j) N(j.companyName ?? ""), F(j.website ?? ""), L(j.bio ?? ""), z(j.githubUsername ?? ""), V(j.twitterUsername ?? ""), U(j.linkedinUrl ?? "");
|
|
23
|
+
else if (!E && C) {
|
|
24
|
+
let e = [C.firstName, C.lastName].filter(Boolean).join(" ");
|
|
25
|
+
e && N(e);
|
|
26
|
+
}
|
|
27
|
+
}, [
|
|
28
|
+
j,
|
|
29
|
+
E,
|
|
30
|
+
C
|
|
31
|
+
]), E && !j ? /* @__PURE__ */ y(i, {
|
|
32
|
+
title: S("devportal.publisherProfileTitle", "Publisher Profile"),
|
|
33
|
+
description: S("devportal.loadingPublisherProfile", "Loading your publisher profile..."),
|
|
34
|
+
children: /* @__PURE__ */ y("div", {
|
|
26
35
|
className: "flex items-center justify-center py-20",
|
|
27
|
-
children: /* @__PURE__ */
|
|
36
|
+
children: /* @__PURE__ */ y(g, { className: "h-8 w-8 animate-spin text-muted-foreground" })
|
|
28
37
|
})
|
|
29
|
-
}) :
|
|
30
|
-
title:
|
|
31
|
-
description:
|
|
32
|
-
children: /* @__PURE__ */
|
|
38
|
+
}) : D && !j ? /* @__PURE__ */ y(i, {
|
|
39
|
+
title: S("devportal.publisherProfileTitle", "Publisher Profile"),
|
|
40
|
+
description: S("devportal.manageStorePublisherPresence", "Manage your store publisher presence"),
|
|
41
|
+
children: /* @__PURE__ */ b("div", {
|
|
33
42
|
className: "flex flex-col items-center justify-center gap-4 py-20",
|
|
34
43
|
children: [
|
|
35
|
-
/* @__PURE__ */
|
|
36
|
-
/* @__PURE__ */
|
|
44
|
+
/* @__PURE__ */ y(p, { className: "h-12 w-12 text-destructive" }),
|
|
45
|
+
/* @__PURE__ */ y("p", {
|
|
37
46
|
className: "text-muted-foreground",
|
|
38
|
-
children:
|
|
47
|
+
children: S("devportal.failedToLoadProfile", "Failed to load profile")
|
|
39
48
|
}),
|
|
40
|
-
/* @__PURE__ */
|
|
41
|
-
onClick: () =>
|
|
49
|
+
/* @__PURE__ */ y("button", {
|
|
50
|
+
onClick: () => O(),
|
|
42
51
|
className: "rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90",
|
|
43
|
-
children:
|
|
52
|
+
children: S("devportal.retryButton", "Retry")
|
|
44
53
|
})
|
|
45
54
|
]
|
|
46
55
|
})
|
|
47
|
-
}) : /* @__PURE__ */
|
|
48
|
-
permission:
|
|
49
|
-
children: /* @__PURE__ */
|
|
50
|
-
title:
|
|
51
|
-
description:
|
|
52
|
-
actions: /* @__PURE__ */
|
|
56
|
+
}) : /* @__PURE__ */ y(s, {
|
|
57
|
+
permission: c.PROFILE_READ,
|
|
58
|
+
children: /* @__PURE__ */ b(i, {
|
|
59
|
+
title: S("devportal.publisherProfileTitle", "Publisher Profile"),
|
|
60
|
+
description: S("devportal.manageMarketplaceAppearance", "Manage how you appear to users in the marketplace"),
|
|
61
|
+
actions: /* @__PURE__ */ b("button", {
|
|
53
62
|
onClick: async () => {
|
|
54
|
-
|
|
55
|
-
|
|
63
|
+
let e = j?.userId ?? C?.id;
|
|
64
|
+
if (e) {
|
|
65
|
+
G("saving");
|
|
56
66
|
try {
|
|
57
|
-
let
|
|
58
|
-
userId:
|
|
67
|
+
let t = await k({ variables: {
|
|
68
|
+
userId: e,
|
|
59
69
|
input: {
|
|
60
|
-
companyName:
|
|
61
|
-
website:
|
|
62
|
-
bio:
|
|
63
|
-
githubUsername:
|
|
64
|
-
twitterUsername:
|
|
65
|
-
linkedinUrl:
|
|
66
|
-
emailNotifications:
|
|
67
|
-
marketingEmails:
|
|
70
|
+
companyName: M || null,
|
|
71
|
+
website: P || null,
|
|
72
|
+
bio: I || null,
|
|
73
|
+
githubUsername: R || null,
|
|
74
|
+
twitterUsername: B || null,
|
|
75
|
+
linkedinUrl: H || null,
|
|
76
|
+
emailNotifications: j?.emailNotifications,
|
|
77
|
+
marketingEmails: j?.marketingEmails
|
|
68
78
|
}
|
|
69
79
|
} });
|
|
70
|
-
if (
|
|
71
|
-
|
|
80
|
+
if (t.error) throw t.error;
|
|
81
|
+
G("saved"), await O(), setTimeout(() => G("idle"), 3e3);
|
|
72
82
|
} catch {
|
|
73
|
-
|
|
83
|
+
G("error"), setTimeout(() => G("idle"), 5e3);
|
|
74
84
|
}
|
|
75
85
|
}
|
|
76
86
|
},
|
|
77
|
-
disabled:
|
|
78
|
-
"aria-disabled": !
|
|
79
|
-
className:
|
|
80
|
-
children: [
|
|
87
|
+
disabled: A || !w,
|
|
88
|
+
"aria-disabled": !w,
|
|
89
|
+
className: t("inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-colors", W === "saved" ? "bg-status-success-bg text-white" : W === "error" ? "bg-destructive text-destructive-foreground" : "bg-primary text-primary-foreground hover:bg-primary/90", A && "opacity-50 cursor-not-allowed"),
|
|
90
|
+
children: [A ? /* @__PURE__ */ y(g, {
|
|
81
91
|
size: 16,
|
|
82
92
|
className: "animate-spin"
|
|
83
|
-
}) :
|
|
93
|
+
}) : y(W === "saved" ? m : W === "error" ? p : _, { size: 16 }), A ? S("devportal.savingButton", "Saving...") : W === "saved" ? S("devportal.savedButton", "Saved!") : W === "error" ? S("devportal.errorButton", "Error") : S("devportal.saveChangesButton", "Save Changes")]
|
|
84
94
|
}),
|
|
85
|
-
children: [/* @__PURE__ */
|
|
95
|
+
children: [/* @__PURE__ */ b("div", {
|
|
86
96
|
className: "flex gap-3 rounded-lg border border-border-subtle bg-status-info-bg-subtle p-4 text-sm text-status-info-text",
|
|
87
|
-
children: [/* @__PURE__ */
|
|
97
|
+
children: [/* @__PURE__ */ y(h, {
|
|
88
98
|
size: 16,
|
|
89
99
|
className: "flex-shrink-0 mt-0.5"
|
|
90
|
-
}), /* @__PURE__ */
|
|
100
|
+
}), /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
|
|
91
101
|
className: "font-medium",
|
|
92
|
-
children:
|
|
93
|
-
}), /* @__PURE__ */
|
|
102
|
+
children: S("devportal.publisherProfilesWorkTitle", "How publisher profiles work")
|
|
103
|
+
}), /* @__PURE__ */ y("p", {
|
|
94
104
|
className: "mt-1 text-status-info-text",
|
|
95
|
-
children:
|
|
105
|
+
children: S("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.")
|
|
96
106
|
})] })]
|
|
97
|
-
}), /* @__PURE__ */
|
|
107
|
+
}), /* @__PURE__ */ b("div", {
|
|
98
108
|
className: "grid grid-cols-1 gap-6 lg:grid-cols-3",
|
|
99
|
-
children: [/* @__PURE__ */
|
|
109
|
+
children: [/* @__PURE__ */ b("div", {
|
|
100
110
|
className: "lg:col-span-2 space-y-6",
|
|
101
|
-
children: [/* @__PURE__ */
|
|
102
|
-
title:
|
|
103
|
-
description:
|
|
104
|
-
children: /* @__PURE__ */
|
|
111
|
+
children: [/* @__PURE__ */ y(a, {
|
|
112
|
+
title: S("devportal.publisherIdentityTitle", "Publisher Identity"),
|
|
113
|
+
description: S("devportal.publisherIdentityDesc", "Displayed on your marketplace listings"),
|
|
114
|
+
children: /* @__PURE__ */ b("div", {
|
|
105
115
|
className: "space-y-4",
|
|
106
116
|
children: [
|
|
107
|
-
/* @__PURE__ */
|
|
108
|
-
label:
|
|
109
|
-
value:
|
|
110
|
-
onChange: (e) =>
|
|
111
|
-
placeholder:
|
|
117
|
+
/* @__PURE__ */ y(o, {
|
|
118
|
+
label: S("devportal.displayNameLabel", "Display Name / Company"),
|
|
119
|
+
value: M,
|
|
120
|
+
onChange: (e) => N(e.target.value),
|
|
121
|
+
placeholder: S("devportal.displayNamePlaceholder", "Your name or company (shown on all your apps)")
|
|
112
122
|
}),
|
|
113
|
-
/* @__PURE__ */
|
|
123
|
+
/* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("label", {
|
|
114
124
|
className: "text-sm font-medium text-foreground",
|
|
115
|
-
children:
|
|
116
|
-
}), /* @__PURE__ */
|
|
117
|
-
value:
|
|
118
|
-
onChange: (e) =>
|
|
119
|
-
placeholder:
|
|
125
|
+
children: S("devportal.bioLabel", "Bio")
|
|
126
|
+
}), /* @__PURE__ */ y("textarea", {
|
|
127
|
+
value: I,
|
|
128
|
+
onChange: (e) => L(e.target.value),
|
|
129
|
+
placeholder: S("devportal.bioPlaceholder", "A short description of you or your company shown on the marketplace..."),
|
|
120
130
|
rows: 3,
|
|
121
131
|
className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring resize-none"
|
|
122
132
|
})] }),
|
|
123
|
-
/* @__PURE__ */
|
|
124
|
-
label:
|
|
125
|
-
value:
|
|
126
|
-
onChange: (e) =>
|
|
127
|
-
placeholder:
|
|
133
|
+
/* @__PURE__ */ y(o, {
|
|
134
|
+
label: S("devportal.websiteLabel", "Website"),
|
|
135
|
+
value: P,
|
|
136
|
+
onChange: (e) => F(e.target.value),
|
|
137
|
+
placeholder: S("devportal.websitePlaceholder", "https://your-website.com")
|
|
128
138
|
})
|
|
129
139
|
]
|
|
130
140
|
})
|
|
131
|
-
}), /* @__PURE__ */
|
|
132
|
-
title:
|
|
133
|
-
description:
|
|
134
|
-
children: /* @__PURE__ */
|
|
141
|
+
}), /* @__PURE__ */ y(a, {
|
|
142
|
+
title: S("devportal.socialLinksTitle", "Social Links"),
|
|
143
|
+
description: S("devportal.socialLinksDesc", "Build trust with your developer community"),
|
|
144
|
+
children: /* @__PURE__ */ b("div", {
|
|
135
145
|
className: "space-y-4",
|
|
136
146
|
children: [
|
|
137
|
-
/* @__PURE__ */
|
|
138
|
-
label:
|
|
139
|
-
value: I,
|
|
140
|
-
onChange: (e) => L(e.target.value),
|
|
141
|
-
placeholder: x("devportal.githubUsernamePlaceholder", "your-github-username")
|
|
142
|
-
}),
|
|
143
|
-
/* @__PURE__ */ v(r, {
|
|
144
|
-
label: x("devportal.twitterUsernameLabel", "Twitter / X Username"),
|
|
147
|
+
/* @__PURE__ */ y(o, {
|
|
148
|
+
label: S("devportal.githubUsernameLabel", "GitHub Username"),
|
|
145
149
|
value: R,
|
|
146
150
|
onChange: (e) => z(e.target.value),
|
|
147
|
-
placeholder:
|
|
151
|
+
placeholder: S("devportal.githubUsernamePlaceholder", "your-github-username")
|
|
148
152
|
}),
|
|
149
|
-
/* @__PURE__ */
|
|
150
|
-
label:
|
|
153
|
+
/* @__PURE__ */ y(o, {
|
|
154
|
+
label: S("devportal.twitterUsernameLabel", "Twitter / X Username"),
|
|
151
155
|
value: B,
|
|
152
156
|
onChange: (e) => V(e.target.value),
|
|
153
|
-
placeholder:
|
|
157
|
+
placeholder: S("devportal.twitterUsernamePlaceholder", "your_twitter")
|
|
158
|
+
}),
|
|
159
|
+
/* @__PURE__ */ y(o, {
|
|
160
|
+
label: S("devportal.linkedinUrlLabel", "LinkedIn URL"),
|
|
161
|
+
value: H,
|
|
162
|
+
onChange: (e) => U(e.target.value),
|
|
163
|
+
placeholder: S("devportal.linkedinUrlPlaceholder", "https://linkedin.com/in/you")
|
|
154
164
|
})
|
|
155
165
|
]
|
|
156
166
|
})
|
|
157
167
|
})]
|
|
158
|
-
}), /* @__PURE__ */
|
|
168
|
+
}), /* @__PURE__ */ b("div", {
|
|
159
169
|
className: "space-y-6",
|
|
160
170
|
children: [
|
|
161
|
-
/* @__PURE__ */
|
|
162
|
-
title:
|
|
163
|
-
children: /* @__PURE__ */
|
|
171
|
+
/* @__PURE__ */ y(a, {
|
|
172
|
+
title: S("devportal.publisherStatusTitle", "Publisher Status"),
|
|
173
|
+
children: /* @__PURE__ */ b("div", {
|
|
164
174
|
className: "flex items-center gap-3",
|
|
165
|
-
children: [/* @__PURE__ */ v
|
|
175
|
+
children: [/* @__PURE__ */ y(v, { className: "h-8 w-8 text-primary" }), /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
|
|
166
176
|
className: "font-medium",
|
|
167
|
-
children:
|
|
168
|
-
}), /* @__PURE__ */
|
|
177
|
+
children: j?.isVerified ? S("devportal.verifiedPublisher", "Verified Publisher") : S("devportal.publisher", "Publisher")
|
|
178
|
+
}), /* @__PURE__ */ y("p", {
|
|
169
179
|
className: "text-xs text-muted-foreground",
|
|
170
|
-
children:
|
|
180
|
+
children: j?.isVerified ? S("devportal.publisherIdentityVerified", "Your publisher identity is verified") : S("devportal.publishFirstAppMessage", "Publish your first app to appear in the marketplace")
|
|
171
181
|
})] })]
|
|
172
182
|
})
|
|
173
183
|
}),
|
|
174
|
-
/* @__PURE__ */
|
|
175
|
-
title:
|
|
176
|
-
children: /* @__PURE__ */
|
|
184
|
+
/* @__PURE__ */ y(a, {
|
|
185
|
+
title: S("devportal.profileCompletenessTitle", "Profile Completeness"),
|
|
186
|
+
children: /* @__PURE__ */ y("div", {
|
|
177
187
|
className: "space-y-2",
|
|
178
188
|
children: [
|
|
179
189
|
{
|
|
180
|
-
label:
|
|
181
|
-
ok: !!
|
|
190
|
+
label: S("devportal.completenessDisplayName", "Display name"),
|
|
191
|
+
ok: !!M
|
|
182
192
|
},
|
|
183
193
|
{
|
|
184
|
-
label:
|
|
185
|
-
ok: !!
|
|
194
|
+
label: S("devportal.completenessBio", "Bio"),
|
|
195
|
+
ok: !!I
|
|
186
196
|
},
|
|
187
197
|
{
|
|
188
|
-
label:
|
|
189
|
-
ok: !!
|
|
198
|
+
label: S("devportal.completenessWebsite", "Website"),
|
|
199
|
+
ok: !!P
|
|
190
200
|
},
|
|
191
201
|
{
|
|
192
|
-
label:
|
|
193
|
-
ok: !!
|
|
202
|
+
label: S("devportal.completenessGithub", "GitHub"),
|
|
203
|
+
ok: !!R
|
|
194
204
|
},
|
|
195
205
|
{
|
|
196
|
-
label:
|
|
197
|
-
ok: !!
|
|
206
|
+
label: S("devportal.completenessSocialLinks", "Social links"),
|
|
207
|
+
ok: !!B || !!H
|
|
198
208
|
}
|
|
199
|
-
].map(({ label: e, ok: t }) => /* @__PURE__ */
|
|
209
|
+
].map(({ label: e, ok: t }) => /* @__PURE__ */ b("div", {
|
|
200
210
|
className: "flex items-center gap-2 text-sm",
|
|
201
|
-
children: [t ? /* @__PURE__ */
|
|
211
|
+
children: [t ? /* @__PURE__ */ y(m, {
|
|
202
212
|
size: 14,
|
|
203
213
|
className: "text-status-success-text"
|
|
204
|
-
}) : /* @__PURE__ */
|
|
214
|
+
}) : /* @__PURE__ */ y("div", { className: "h-3.5 w-3.5 rounded-full border-2 border-muted-foreground" }), /* @__PURE__ */ y("span", {
|
|
205
215
|
className: t ? "text-foreground" : "text-muted-foreground",
|
|
206
216
|
children: e
|
|
207
217
|
})]
|
|
208
218
|
}, e))
|
|
209
219
|
})
|
|
210
220
|
}),
|
|
211
|
-
/* @__PURE__ */
|
|
212
|
-
title:
|
|
213
|
-
children: /* @__PURE__ */
|
|
221
|
+
/* @__PURE__ */ y(a, {
|
|
222
|
+
title: S("devportal.marketplaceStatsTitle", "Marketplace Stats"),
|
|
223
|
+
children: /* @__PURE__ */ b("div", {
|
|
214
224
|
className: "space-y-3 text-sm",
|
|
215
225
|
children: [
|
|
216
|
-
/* @__PURE__ */
|
|
226
|
+
/* @__PURE__ */ b("div", {
|
|
217
227
|
className: "flex justify-between",
|
|
218
|
-
children: [/* @__PURE__ */
|
|
228
|
+
children: [/* @__PURE__ */ y("span", {
|
|
219
229
|
className: "text-muted-foreground",
|
|
220
|
-
children:
|
|
221
|
-
}), /* @__PURE__ */
|
|
230
|
+
children: S("devportal.publishedAppsLabel", "Published apps")
|
|
231
|
+
}), /* @__PURE__ */ y("span", {
|
|
222
232
|
className: "font-semibold",
|
|
223
|
-
children:
|
|
233
|
+
children: j?.applicationCount ?? 0
|
|
224
234
|
})]
|
|
225
235
|
}),
|
|
226
|
-
/* @__PURE__ */
|
|
236
|
+
/* @__PURE__ */ b("div", {
|
|
227
237
|
className: "flex justify-between",
|
|
228
|
-
children: [/* @__PURE__ */
|
|
238
|
+
children: [/* @__PURE__ */ y("span", {
|
|
229
239
|
className: "text-muted-foreground",
|
|
230
|
-
children:
|
|
231
|
-
}), /* @__PURE__ */
|
|
240
|
+
children: S("devportal.totalInstallsLabel", "Total installs")
|
|
241
|
+
}), /* @__PURE__ */ y("span", {
|
|
232
242
|
className: "font-semibold",
|
|
233
|
-
children:
|
|
243
|
+
children: j?.totalInstalls ?? 0
|
|
234
244
|
})]
|
|
235
245
|
}),
|
|
236
|
-
/* @__PURE__ */
|
|
246
|
+
/* @__PURE__ */ b("div", {
|
|
237
247
|
className: "flex justify-between",
|
|
238
|
-
children: [/* @__PURE__ */
|
|
248
|
+
children: [/* @__PURE__ */ y("span", {
|
|
239
249
|
className: "text-muted-foreground",
|
|
240
|
-
children:
|
|
241
|
-
}), /* @__PURE__ */
|
|
250
|
+
children: S("devportal.avgRatingLabel", "Avg rating")
|
|
251
|
+
}), /* @__PURE__ */ y("span", {
|
|
242
252
|
className: "font-semibold",
|
|
243
|
-
children:
|
|
253
|
+
children: j?.averageRating ? j.averageRating.toFixed(1) : "—"
|
|
244
254
|
})]
|
|
245
255
|
})
|
|
246
256
|
]
|
|
@@ -253,6 +263,6 @@ var b = () => {
|
|
|
253
263
|
});
|
|
254
264
|
};
|
|
255
265
|
//#endregion
|
|
256
|
-
export {
|
|
266
|
+
export { x as PublisherProfilePage };
|
|
257
267
|
|
|
258
268
|
//# 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 {\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 { 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 }\n }, [profile]);\n\n const handleSave = async () => {\n if (!profile) return;\n setSaveStatus(\"saving\");\n try {\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-muted-foreground\" />\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-destructive\" />\n <p className=\"text-muted-foreground\">\n {tr(\"devportal.failedToLoadProfile\", \"Failed to load profile\")}\n </p>\n <button\n onClick={() => refetch()}\n className=\"rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90\"\n >\n {tr(\"devportal.retryButton\", \"Retry\")}\n </button>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PermissionGuard permission={DEVPORTAL_PERMISSIONS.PROFILE_READ}>\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 actions={\n <button\n onClick={handleSave}\n disabled={saving || !profile || !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-destructive text-destructive-foreground\"\n : \"bg-primary text-primary-foreground hover:bg-primary/90\",\n (saving || !profile) && \"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 {/* Info banner */}\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-foreground\">\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-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-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(\"devportal.githubUsernameLabel\", \"GitHub Username\")}\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(\"devportal.verifiedPublisher\", \"Verified Publisher\")\n : tr(\"devportal.publisher\", \"Publisher\")}\n </p>\n <p className=\"text-xs text-muted-foreground\">\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 { label: tr(\"devportal.completenessBio\", \"Bio\"), ok: !!bio },\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 key={label} className=\"flex items-center gap-2 text-sm\">\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-foreground\" : \"text-muted-foreground\"\n }\n >\n {label}\n </span>\n </div>\n ))}\n </div>\n </PageSection>\n\n {/* Stats */}\n <PageSection\n title={tr(\"devportal.marketplaceStatsTitle\", \"Marketplace Stats\")}\n >\n <div className=\"space-y-3 text-sm\">\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">\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-muted-foreground\">\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-muted-foreground\">\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 </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;AA8BA,IAAa,UAAiC;CAC5C,IAAM,EAAE,SAAM,GAAS,EACjB,KAAM,GAAa,MAA6B;EACpD,IAAM,IAAQ,EAAE,EAAI;AACpB,SAAO,MAAU,IAAM,IAAW;IAE9B,EAAE,SAAS,MAAY,EAC3B,EAAsB,eACvB,EACK,EAAE,SAAM,YAAS,UAAO,eAAY,EAA8B,EACtE,aAAa,qBACd,CAAC,EAEI,CAAC,GAAe,EAAE,SAAS,OAC/B,GAAmC,EAE/B,IAAU,GAAM,oBAGhB,CAAC,GAAa,KAAkB,EAAS,GAAG,EAC5C,CAAC,GAAS,KAAc,EAAS,GAAG,EACpC,CAAC,GAAK,KAAU,EAAS,GAAG,EAC5B,CAAC,GAAgB,KAAqB,EAAS,GAAG,EAClD,CAAC,GAAiB,KAAsB,EAAS,GAAG,EACpD,CAAC,GAAa,KAAkB,EAAS,GAAG,EAE5C,CAAC,GAAY,KAAiB,EAElC,OAAO;AAsFT,QApFA,QAAgB;AACd,EAAI,MACF,EAAe,EAAQ,eAAe,GAAG,EACzC,EAAW,EAAQ,WAAW,GAAG,EACjC,EAAO,EAAQ,OAAO,GAAG,EACzB,EAAkB,EAAQ,kBAAkB,GAAG,EAC/C,EAAmB,EAAQ,mBAAmB,GAAG,EACjD,EAAe,EAAQ,eAAe,GAAG;IAE1C,CAAC,EAAQ,CAAC,EAkCT,KAAW,CAAC,IAEZ,kBAAC,GAAD;EACE,OAAO,EAAG,mCAAmC,oBAAoB;EACjE,aAAa,EACX,qCACA,oCACD;YAED,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,GAAD,EAAS,WAAU,8CAA+C,CAAA;GAC9D,CAAA;EACK,CAAA,GAIb,KAAS,CAAC,IAEV,kBAAC,GAAD;EACE,OAAO,EAAG,mCAAmC,oBAAoB;EACjE,aAAa,EACX,0CACA,uCACD;YAED,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,GAAD,EAAa,WAAU,8BAA+B,CAAA;IACtD,kBAAC,KAAD;KAAG,WAAU;eACV,EAAG,iCAAiC,yBAAyB;KAC5D,CAAA;IACJ,kBAAC,UAAD;KACE,eAAe,GAAS;KACxB,WAAU;eAET,EAAG,yBAAyB,QAAQ;KAC9B,CAAA;IACL;;EACK,CAAA,GAKf,kBAAC,GAAD;EAAiB,YAAY,EAAsB;YACjD,kBAAC,GAAD;GACE,OAAO,EAAG,mCAAmC,oBAAoB;GACjE,aAAa,EACX,yCACA,oDACD;GACD,SACE,kBAAC,UAAD;IACE,SAnFS,YAAY;AACxB,YACL;QAAc,SAAS;AACvB,UAAI;OACF,IAAM,IAAS,MAAM,EAAc,EACjC,WAAW;QACT,QAAQ,EAAQ;QAChB,OAAO;SACL,aAAa,KAAe;SAC5B,SAAS,KAAW;SACpB,KAAK,KAAO;SACZ,gBAAgB,KAAkB;SAClC,iBAAiB,KAAmB;SACpC,aAAa,KAAe;SAE5B,oBAAoB,EAAQ;SAC5B,iBAAiB,EAAQ;SAC1B;QACF,EACF,CAAC;AACF,WAAI,EAAO,MACT,OAAM,EAAO;AAIf,OAFA,EAAc,QAAQ,EACtB,MAAM,GAAS,EACf,iBAAiB,EAAc,OAAO,EAAE,IAAK;cACvC;AAEN,OADA,EAAc,QAAQ,EACtB,iBAAiB,EAAc,OAAO,EAAE,IAAK;;;;IAwDvC,UAAU,KAAU,CAAC,KAAW,CAAC;IACjC,iBAAe,CAAC;IAChB,WAAW,EACT,6FACA,MAAe,UACX,oCACA,MAAe,UACb,+CACA,2DACL,KAAU,CAAC,MAAY,gCACzB;cAZH,CAcG,IACC,kBAAC,GAAD;KAAS,MAAM;KAAI,WAAU;KAAiB,CAAA,GAE9C,EADE,MAAe,UAChB,IACC,MAAe,UAChB,IAEA,GAJD,EAAc,MAAM,IAAM,CAIR,EAEnB,IACG,EAAG,0BAA0B,YAAY,GACzC,MAAe,UACb,EAAG,yBAAyB,SAAS,GACrC,MAAe,UACb,EAAG,yBAAyB,QAAQ,GACpC,EAAG,+BAA+B,eAAe,CAClD;;aArCb,CAyCE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KAAM,MAAM;KAAI,WAAU;KAAyB,CAAA,EACnD,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;KAAG,WAAU;eACV,EACC,wCACA,8BACD;KACC,CAAA,EACJ,kBAAC,KAAD;KAAG,WAAU;eACV,EACC,uCACA,qQACD;KACC,CAAA,CACA,EAAA,CAAA,CACF;OAEN,kBAAC,OAAD;IAAK,WAAU;cAAf,CAEE,kBAAC,OAAD;KAAK,WAAU;eAAf,CAEE,kBAAC,GAAD;MACE,OAAO,EACL,oCACA,qBACD;MACD,aAAa,EACX,mCACA,yCACD;gBAED,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,GAAD;SACE,OAAO,EACL,8BACA,yBACD;SACD,OAAO;SACP,WAAW,MAAM,EAAe,EAAE,OAAO,MAAM;SAC/C,aAAa,EACX,oCACA,gDACD;SACD,CAAA;QACF,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;SAAO,WAAU;mBACd,EAAG,sBAAsB,MAAM;SAC1B,CAAA,EACR,kBAAC,YAAD;SACE,OAAO;SACP,WAAW,MAAM,EAAO,EAAE,OAAO,MAAM;SACvC,aAAa,EACX,4BACA,yEACD;SACD,MAAM;SACN,WAAU;SACV,CAAA,CACE,EAAA,CAAA;QACN,kBAAC,GAAD;SACE,OAAO,EAAG,0BAA0B,UAAU;SAC9C,OAAO;SACP,WAAW,MAAM,EAAW,EAAE,OAAO,MAAM;SAC3C,aAAa,EACX,gCACA,2BACD;SACD,CAAA;QACE;;MACM,CAAA,EAGd,kBAAC,GAAD;MACE,OAAO,EAAG,8BAA8B,eAAe;MACvD,aAAa,EACX,6BACA,4CACD;gBAED,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,GAAD;SACE,OAAO,EAAG,iCAAiC,kBAAkB;SAC7D,OAAO;SACP,WAAW,MAAM,EAAkB,EAAE,OAAO,MAAM;SAClD,aAAa,EACX,uCACA,uBACD;SACD,CAAA;QACF,kBAAC,GAAD;SACE,OAAO,EACL,kCACA,uBACD;SACD,OAAO;SACP,WAAW,MAAM,EAAmB,EAAE,OAAO,MAAM;SACnD,aAAa,EACX,wCACA,eACD;SACD,CAAA;QACF,kBAAC,GAAD;SACE,OAAO,EAAG,8BAA8B,eAAe;SACvD,OAAO;SACP,WAAW,MAAM,EAAe,EAAE,OAAO,MAAM;SAC/C,aAAa,EACX,oCACA,8BACD;SACD,CAAA;QACE;;MACM,CAAA,CACV;QAGN,kBAAC,OAAD;KAAK,WAAU;eAAf;MAEE,kBAAC,GAAD;OACE,OAAO,EAAG,kCAAkC,mBAAmB;iBAE/D,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD,EAAO,WAAU,wBAAyB,CAAA,EAC1C,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;SAAG,WAAU;mBACV,GAAS,aACN,EAAG,+BAA+B,qBAAqB,GACvD,EAAG,uBAAuB,YAAY;SACxC,CAAA,EACJ,kBAAC,KAAD;SAAG,WAAU;mBACV,GAAS,aACN,EACE,uCACA,sCACD,GACD,EACE,oCACA,sDACD;SACH,CAAA,CACA,EAAA,CAAA,CACF;;OACM,CAAA;MAGd,kBAAC,GAAD;OACE,OAAO,EACL,sCACA,uBACD;iBAED,kBAAC,OAAD;QAAK,WAAU;kBACZ;SACC;UACE,OAAO,EACL,qCACA,eACD;UACD,IAAI,CAAC,CAAC;UACP;SACD;UAAE,OAAO,EAAG,6BAA6B,MAAM;UAAE,IAAI,CAAC,CAAC;UAAK;SAC5D;UACE,OAAO,EAAG,iCAAiC,UAAU;UACrD,IAAI,CAAC,CAAC;UACP;SACD;UACE,OAAO,EAAG,gCAAgC,SAAS;UACnD,IAAI,CAAC,CAAC;UACP;SACD;UACE,OAAO,EACL,qCACA,eACD;UACD,IAAI,CAAC,CAAC,KAAmB,CAAC,CAAC;UAC5B;SACF,CAAC,KAAK,EAAE,UAAO,YACd,kBAAC,OAAD;SAAiB,WAAU;mBAA3B,CACG,IACC,kBAAC,GAAD;UACE,MAAM;UACN,WAAU;UACV,CAAA,GAEF,kBAAC,OAAD,EAAK,WAAU,6DAA8D,CAAA,EAE/E,kBAAC,QAAD;UACE,WACE,IAAK,oBAAoB;oBAG1B;UACI,CAAA,CACH;WAhBI,EAgBJ,CACN;QACE,CAAA;OACM,CAAA;MAGd,kBAAC,GAAD;OACE,OAAO,EAAG,mCAAmC,oBAAoB;iBAEjE,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,QAAD;WAAM,WAAU;qBACb,EAAG,gCAAgC,iBAAiB;WAChD,CAAA,EACP,kBAAC,QAAD;WAAM,WAAU;qBACb,GAAS,oBAAoB;WACzB,CAAA,CACH;;SACN,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,QAAD;WAAM,WAAU;qBACb,EAAG,gCAAgC,iBAAiB;WAChD,CAAA,EACP,kBAAC,QAAD;WAAM,WAAU;qBACb,GAAS,iBAAiB;WACtB,CAAA,CACH;;SACN,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,QAAD;WAAM,WAAU;qBACb,EAAG,4BAA4B,aAAa;WACxC,CAAA,EACP,kBAAC,QAAD;WAAM,WAAU;qBACb,GAAS,gBACN,EAAQ,cAAc,QAAQ,EAAE,GAChC;WACC,CAAA,CACH;;SACF;;OACM,CAAA;MACV;OACF;MACK;;EACG,CAAA"}
|
|
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-muted-foreground\" />\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-destructive\" />\n <p className=\"text-muted-foreground\">\n {tr(\"devportal.failedToLoadProfile\", \"Failed to load profile\")}\n </p>\n <button\n onClick={() => refetch()}\n className=\"rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90\"\n >\n {tr(\"devportal.retryButton\", \"Retry\")}\n </button>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PermissionGuard permission={DEVPORTAL_PERMISSIONS.PROFILE_READ}>\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 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-destructive text-destructive-foreground\"\n : \"bg-primary text-primary-foreground hover:bg-primary/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 {/* Info banner */}\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-foreground\">\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-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-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(\"devportal.githubUsernameLabel\", \"GitHub Username\")}\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(\"devportal.verifiedPublisher\", \"Verified Publisher\")\n : tr(\"devportal.publisher\", \"Publisher\")}\n </p>\n <p className=\"text-xs text-muted-foreground\">\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 { label: tr(\"devportal.completenessBio\", \"Bio\"), ok: !!bio },\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 key={label} className=\"flex items-center gap-2 text-sm\">\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-foreground\" : \"text-muted-foreground\"\n }\n >\n {label}\n </span>\n </div>\n ))}\n </div>\n </PageSection>\n\n {/* Stats */}\n <PageSection\n title={tr(\"devportal.marketplaceStatsTitle\", \"Marketplace Stats\")}\n >\n <div className=\"space-y-3 text-sm\">\n <div className=\"flex justify-between\">\n <span className=\"text-muted-foreground\">\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-muted-foreground\">\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-muted-foreground\">\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 </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
|