@burdenoff/microfe-devportal 2026.1112.2 → 2026.1113.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/dist/devportal/DevportalRoot.js +65 -119
  2. package/dist/devportal/DevportalRoot.js.map +1 -1
  3. package/dist/devportal/components/AppCard.js +72 -69
  4. package/dist/devportal/components/AppCard.js.map +1 -1
  5. package/dist/devportal/components/DeveloperSettingsHub.d.ts +6 -0
  6. package/dist/devportal/components/DeveloperSettingsHub.js +59 -0
  7. package/dist/devportal/components/DeveloperSettingsHub.js.map +1 -0
  8. package/dist/devportal/components/ImageUploadField.js +82 -80
  9. package/dist/devportal/components/ImageUploadField.js.map +1 -1
  10. package/dist/devportal/components/SectionNav.d.ts +1 -1
  11. package/dist/devportal/components/SectionNav.js +60 -36
  12. package/dist/devportal/components/SectionNav.js.map +1 -1
  13. package/dist/devportal/components/StoreImage.d.ts +15 -0
  14. package/dist/devportal/components/StoreImage.js +30 -0
  15. package/dist/devportal/components/StoreImage.js.map +1 -0
  16. package/dist/devportal/components/index.d.ts +1 -0
  17. package/dist/devportal/components/index.js +17 -16
  18. package/dist/devportal/hooks/usePackageUpload.d.ts +46 -4
  19. package/dist/devportal/hooks/usePackageUpload.js +90 -36
  20. package/dist/devportal/hooks/usePackageUpload.js.map +1 -1
  21. package/dist/devportal/pages/AdminReviewPage.js +205 -202
  22. package/dist/devportal/pages/AdminReviewPage.js.map +1 -1
  23. package/dist/devportal/pages/AnalyticsDashboardPage.js +186 -179
  24. package/dist/devportal/pages/AnalyticsDashboardPage.js.map +1 -1
  25. package/dist/devportal/pages/ApiKeysPage.js +113 -111
  26. package/dist/devportal/pages/ApiKeysPage.js.map +1 -1
  27. package/dist/devportal/pages/AppLogsPage.js +80 -84
  28. package/dist/devportal/pages/AppLogsPage.js.map +1 -1
  29. package/dist/devportal/pages/ApplicationDetailPage.js +529 -504
  30. package/dist/devportal/pages/ApplicationDetailPage.js.map +1 -1
  31. package/dist/devportal/pages/ApplicationsPage.js +186 -183
  32. package/dist/devportal/pages/ApplicationsPage.js.map +1 -1
  33. package/dist/devportal/pages/CreateApiKeyPage.js +163 -166
  34. package/dist/devportal/pages/CreateApiKeyPage.js.map +1 -1
  35. package/dist/devportal/pages/CreateOAuthClientPage.js +134 -130
  36. package/dist/devportal/pages/CreateOAuthClientPage.js.map +1 -1
  37. package/dist/devportal/pages/CreatePhysicalItemPage.js +2 -2
  38. package/dist/devportal/pages/CreatePhysicalItemPage.js.map +1 -1
  39. package/dist/devportal/pages/DelegationsPage.js +11 -11
  40. package/dist/devportal/pages/DocumentationPage.js +100 -94
  41. package/dist/devportal/pages/DocumentationPage.js.map +1 -1
  42. package/dist/devportal/pages/EditApplicationPage.js +379 -377
  43. package/dist/devportal/pages/EditApplicationPage.js.map +1 -1
  44. package/dist/devportal/pages/EditPhysicalItemPage.js +312 -307
  45. package/dist/devportal/pages/EditPhysicalItemPage.js.map +1 -1
  46. package/dist/devportal/pages/InvitationDecisionPage.js +83 -79
  47. package/dist/devportal/pages/InvitationDecisionPage.js.map +1 -1
  48. package/dist/devportal/pages/ListingPreviewPage.js +175 -171
  49. package/dist/devportal/pages/ListingPreviewPage.js.map +1 -1
  50. package/dist/devportal/pages/OAuthClientDetailPage.js +76 -76
  51. package/dist/devportal/pages/OAuthClientDetailPage.js.map +1 -1
  52. package/dist/devportal/pages/OAuthClientsPage.js +126 -124
  53. package/dist/devportal/pages/OAuthClientsPage.js.map +1 -1
  54. package/dist/devportal/pages/OrganizationDetailPage.js +19 -19
  55. package/dist/devportal/pages/OrganizationMembersPage.js +223 -204
  56. package/dist/devportal/pages/OrganizationMembersPage.js.map +1 -1
  57. package/dist/devportal/pages/ResourcesPage.d.ts +6 -0
  58. package/dist/devportal/pages/ResourcesPage.js +171 -155
  59. package/dist/devportal/pages/ResourcesPage.js.map +1 -1
  60. package/dist/devportal/pages/SellerDashboardPage.js +117 -115
  61. package/dist/devportal/pages/SellerDashboardPage.js.map +1 -1
  62. package/dist/devportal/pages/SellerItemsPage.js +202 -199
  63. package/dist/devportal/pages/SellerItemsPage.js.map +1 -1
  64. package/dist/devportal/pages/SettingsPage.js +330 -315
  65. package/dist/devportal/pages/SettingsPage.js.map +1 -1
  66. package/dist/devportal/pages/SetupPage.js +5 -5
  67. package/dist/devportal/pages/StoreSubmissionPage.js +133 -131
  68. package/dist/devportal/pages/StoreSubmissionPage.js.map +1 -1
  69. package/dist/devportal/pages/WebhookDetailPage.js +6 -6
  70. package/dist/devportal/pages/WebhooksPage.js +39 -39
  71. package/dist/devportal/pages/WebhooksPage.js.map +1 -1
  72. package/dist/devportal/utils/appDetailTabs.d.ts +73 -0
  73. package/dist/devportal/utils/appDetailTabs.js +62 -0
  74. package/dist/devportal/utils/appDetailTabs.js.map +1 -0
  75. package/dist/devportal/utils/developerNav.d.ts +39 -0
  76. package/dist/devportal/utils/developerNav.js +304 -0
  77. package/dist/devportal/utils/developerNav.js.map +1 -0
  78. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"InvitationDecisionPage.js","names":["InvitationDecisionPage","useParams","useDevportal","useGetInvitationByTokenQuery","token","acceptInvitation","accepting","acceptedData","useAcceptInvitationMutation","rejectInvitation","rejecting","rejectedData","useRejectInvitationMutation","invitation","data","acceptedMember","rejected","handleAccept","handleReject","loading","PageLayout","Loader2","error","EmptyState","XCircle","CheckCircle","navigate","basePath","PageSection","Mail","Shield"],"sources":["../../../src/devportal/pages/InvitationDecisionPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useParams } from \"react-router\";\nimport { CheckCircle, Loader2, Mail, Shield, XCircle } from \"lucide-react\";\n\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport {\n useAcceptInvitationMutation,\n useGetInvitationByTokenQuery,\n useRejectInvitationMutation,\n} from \"../hooks\";\n\nexport const InvitationDecisionPage: FC = () => {\n const { token } = useParams<{ token: string }>();\n const { navigate, basePath } = useDevportal();\n\n const { data, loading, error } = useGetInvitationByTokenQuery({\n variables: { token: token ?? \"\" },\n skip: !token,\n fetchPolicy: \"cache-and-network\",\n });\n\n const [acceptInvitation, { loading: accepting, data: acceptedData }] =\n useAcceptInvitationMutation();\n const [rejectInvitation, { loading: rejecting, data: rejectedData }] =\n useRejectInvitationMutation();\n\n const invitation = data?.developerOrgInvitationByToken;\n const acceptedMember = acceptedData?.acceptDeveloperOrgInvitation;\n const rejected = rejectedData?.rejectDeveloperOrgInvitation;\n\n const handleAccept = async () => {\n if (!token) return;\n await acceptInvitation({ variables: { token } });\n };\n\n const handleReject = async () => {\n if (!token) return;\n await rejectInvitation({ variables: { token } });\n };\n\n if (loading && !invitation) {\n return (\n <PageLayout title=\"Developer Team Invitation\">\n <div className=\"flex items-center justify-center py-16 text-text-secondary\">\n <Loader2 className=\"h-8 w-8 animate-spin\" />\n </div>\n </PageLayout>\n );\n }\n\n if (error || !invitation) {\n return (\n <PageLayout title=\"Developer Team Invitation\">\n <EmptyState\n icon={<XCircle size={32} className=\"text-status-error-text\" />}\n title=\"Invitation not available\"\n description={\n error?.message ||\n \"This invitation is invalid, expired, or not available to your signed-in account.\"\n }\n />\n </PageLayout>\n );\n }\n\n if (acceptedMember) {\n return (\n <PageLayout title=\"Invitation accepted\">\n <EmptyState\n icon={<CheckCircle size={32} className=\"text-status-success-text\" />}\n title=\"You joined the developer organization\"\n description={`You now have ${invitation.role.toLowerCase()} access to ${invitation.organization.name}.`}\n action={\n <button\n type=\"button\"\n onClick={() =>\n navigate?.(\n `${basePath}/organizations/${invitation.organization.id}`,\n )\n }\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n Open organization\n </button>\n }\n />\n </PageLayout>\n );\n }\n\n if (rejected) {\n return (\n <PageLayout title=\"Invitation declined\">\n <EmptyState\n icon={<XCircle size={32} className=\"text-status-warning-text\" />}\n title=\"Invitation declined\"\n description={`You declined the invitation to join ${invitation.organization.name}.`}\n action={\n <button\n type=\"button\"\n onClick={() => navigate?.(`${basePath}`)}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-seam px-4 py-2 text-sm font-medium hover:bg-bg-sunken\"\n >\n Return to Devportal\n </button>\n }\n />\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Developer Team Invitation\"\n description=\"Review your invitation to join a developer organization\"\n >\n <div className=\"mx-auto max-w-2xl space-y-6\">\n <PageSection title=\"Invitation details\">\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-6 space-y-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">Organization</p>\n <p className=\"text-lg font-semibold text-text-primary\">\n {invitation.organization.name}\n </p>\n </div>\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div>\n <p className=\"text-sm text-text-secondary\">Invited email</p>\n <p className=\"flex items-center gap-2 text-text-primary\">\n <Mail size={14} />\n {invitation.invitedEmail}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Role</p>\n <p className=\"flex items-center gap-2 text-text-primary\">\n <Shield size={14} />\n {invitation.role}\n </p>\n </div>\n </div>\n {invitation.message ? (\n <div>\n <p className=\"text-sm text-text-secondary\">Message</p>\n <p className=\"rounded-md bg-bg-sunken px-3 py-2 text-sm text-text-primary whitespace-pre-line\">\n {invitation.message}\n </p>\n </div>\n ) : null}\n <p className=\"text-xs text-text-secondary\">\n Expires on {new Date(invitation.expiresAt).toLocaleString()}\n </p>\n </div>\n </PageSection>\n\n <div className=\"flex flex-wrap gap-3 justify-end\">\n <button\n type=\"button\"\n onClick={() => void handleReject()}\n disabled={accepting || rejecting}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-seam px-4 py-2 text-sm font-medium hover:bg-bg-sunken disabled:opacity-50\"\n >\n {rejecting ? <Loader2 size={14} className=\"animate-spin\" /> : null}\n Decline\n </button>\n <button\n type=\"button\"\n onClick={() => void handleAccept()}\n disabled={accepting || rejecting}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:opacity-50\"\n >\n {accepting ? <Loader2 size={14} className=\"animate-spin\" /> : null}\n Accept invitation\n </button>\n </div>\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"InvitationDecisionPage.js","names":["InvitationDecisionPage","useParams","tr","useTr","useDevportal","useGetInvitationByTokenQuery","token","acceptInvitation","accepting","acceptedData","useAcceptInvitationMutation","rejectInvitation","rejecting","rejectedData","useRejectInvitationMutation","invitation","data","acceptedMember","rejected","handleAccept","handleReject","invitationTitle","loading","PageLayout","Loader2","error","EmptyState","XCircle","CheckCircle","navigate","basePath","PageSection","Mail","Shield"],"sources":["../../../src/devportal/pages/InvitationDecisionPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useParams } from \"react-router\";\nimport { CheckCircle, Loader2, Mail, Shield, XCircle } from \"lucide-react\";\n\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport {\n useAcceptInvitationMutation,\n useGetInvitationByTokenQuery,\n useRejectInvitationMutation,\n} from \"../hooks\";\nimport { useTr } from \"../utils/i18n\";\n\nexport const InvitationDecisionPage: FC = () => {\n const { token } = useParams<{ token: string }>();\n const tr = useTr();\n const { navigate, basePath } = useDevportal();\n\n const { data, loading, error } = useGetInvitationByTokenQuery({\n variables: { token: token ?? \"\" },\n skip: !token,\n fetchPolicy: \"cache-and-network\",\n });\n\n const [acceptInvitation, { loading: accepting, data: acceptedData }] =\n useAcceptInvitationMutation();\n const [rejectInvitation, { loading: rejecting, data: rejectedData }] =\n useRejectInvitationMutation();\n\n const invitation = data?.developerOrgInvitationByToken;\n const acceptedMember = acceptedData?.acceptDeveloperOrgInvitation;\n const rejected = rejectedData?.rejectDeveloperOrgInvitation;\n\n const handleAccept = async () => {\n if (!token) return;\n await acceptInvitation({ variables: { token } });\n };\n\n const handleReject = async () => {\n if (!token) return;\n await rejectInvitation({ variables: { token } });\n };\n\n const invitationTitle = tr(\n \"devportal.invitation.title\",\n \"Developer Team Invitation\",\n );\n\n if (loading && !invitation) {\n return (\n <PageLayout title={invitationTitle}>\n <div className=\"flex items-center justify-center py-16 text-text-secondary\">\n <Loader2 className=\"h-8 w-8 animate-spin\" />\n </div>\n </PageLayout>\n );\n }\n\n if (error || !invitation) {\n return (\n <PageLayout title={invitationTitle}>\n <EmptyState\n icon={<XCircle size={32} className=\"text-status-error-text\" />}\n title={tr(\n \"devportal.invitation.unavailableTitle\",\n \"Invitation not available\",\n )}\n description={\n error?.message ||\n tr(\n \"devportal.invitation.unavailableDescription\",\n \"This invitation is invalid, expired, or not available to your signed-in account.\",\n )\n }\n />\n </PageLayout>\n );\n }\n\n if (acceptedMember) {\n return (\n <PageLayout\n title={tr(\"devportal.invitation.acceptedTitle\", \"Invitation accepted\")}\n >\n <EmptyState\n icon={<CheckCircle size={32} className=\"text-status-success-text\" />}\n title={tr(\n \"devportal.invitation.joinedTitle\",\n \"You joined the developer organization\",\n )}\n description={tr(\n \"devportal.invitation.joinedDescription\",\n \"You now have {{role}} access to {{organization}}.\",\n {\n role: invitation.role.toLowerCase(),\n organization: invitation.organization.name,\n },\n )}\n action={\n <button\n type=\"button\"\n onClick={() =>\n navigate?.(\n `${basePath}/organizations/${invitation.organization.id}`,\n )\n }\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n {tr(\"devportal.invitation.openOrganization\", \"Open organization\")}\n </button>\n }\n />\n </PageLayout>\n );\n }\n\n if (rejected) {\n return (\n <PageLayout\n title={tr(\"devportal.invitation.declinedTitle\", \"Invitation declined\")}\n >\n <EmptyState\n icon={<XCircle size={32} className=\"text-status-warning-text\" />}\n title={tr(\n \"devportal.invitation.declinedTitle\",\n \"Invitation declined\",\n )}\n description={tr(\n \"devportal.invitation.declinedDescription\",\n \"You declined the invitation to join {{organization}}.\",\n { organization: invitation.organization.name },\n )}\n action={\n <button\n type=\"button\"\n onClick={() => navigate?.(`${basePath}`)}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-seam px-4 py-2 text-sm font-medium hover:bg-bg-sunken\"\n >\n {tr(\n \"devportal.invitation.returnToDevportal\",\n \"Return to Devportal\",\n )}\n </button>\n }\n />\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title={invitationTitle}\n description={tr(\n \"devportal.invitation.reviewDescription\",\n \"Review your invitation to join a developer organization\",\n )}\n >\n <div className=\"mx-auto max-w-2xl space-y-6\">\n <PageSection\n title={tr(\"devportal.invitation.detailsTitle\", \"Invitation details\")}\n >\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-6 space-y-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">\n {tr(\"devportal.invitation.organization\", \"Organization\")}\n </p>\n <p className=\"text-lg font-semibold text-text-primary\">\n {invitation.organization.name}\n </p>\n </div>\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div>\n <p className=\"text-sm text-text-secondary\">\n {tr(\"devportal.invitation.invitedEmail\", \"Invited email\")}\n </p>\n <p className=\"flex items-center gap-2 text-text-primary\">\n <Mail size={14} />\n {invitation.invitedEmail}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">\n {tr(\"devportal.invitation.role\", \"Role\")}\n </p>\n <p className=\"flex items-center gap-2 text-text-primary\">\n <Shield size={14} />\n {invitation.role}\n </p>\n </div>\n </div>\n {invitation.message ? (\n <div>\n <p className=\"text-sm text-text-secondary\">\n {tr(\"devportal.invitation.message\", \"Message\")}\n </p>\n <p className=\"rounded-md bg-bg-sunken px-3 py-2 text-sm text-text-primary whitespace-pre-line\">\n {invitation.message}\n </p>\n </div>\n ) : null}\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.invitation.expiresOn\", \"Expires on {{date}}\", {\n date: new Date(invitation.expiresAt).toLocaleString(),\n })}\n </p>\n </div>\n </PageSection>\n\n <div className=\"flex flex-wrap gap-3 justify-end\">\n <button\n type=\"button\"\n onClick={() => void handleReject()}\n disabled={accepting || rejecting}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-seam px-4 py-2 text-sm font-medium hover:bg-bg-sunken disabled:opacity-50\"\n >\n {rejecting ? <Loader2 size={14} className=\"animate-spin\" /> : null}\n {tr(\"devportal.invitation.decline\", \"Decline\")}\n </button>\n <button\n type=\"button\"\n onClick={() => void handleAccept()}\n disabled={accepting || rejecting}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:opacity-50\"\n >\n {accepting ? <Loader2 size={14} className=\"animate-spin\" /> : null}\n {tr(\"devportal.invitation.accept\", \"Accept invitation\")}\n </button>\n </div>\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
@@ -2,16 +2,17 @@ import { PageLayout as e, PageSection as t } from "../components/PageLayout.js";
2
2
  import { Alert as n } from "../components/ConfirmDialog.js";
3
3
  import { useDevportal as r } from "../providers/DevportalProvider.js";
4
4
  import "../components/index.js";
5
- import { PermissionGuard as i } from "../components/PermissionGuard.js";
6
- import { useGetApplicationQuery as a } from "../../generated/global-operations.js";
7
- import { useEffect as o } from "react";
8
- import { Markdown as s } from "@burdenoff/fe-libs/shared/components";
9
- import { CheckCircle as c, Download as l, ExternalLink as u, Eye as d, FileText as f, Globe as p, Loader2 as m, Shield as h, Star as g, Tag as _ } from "lucide-react";
10
- import { useParams as v } from "react-router";
11
- import { jsx as y, jsxs as b } from "react/jsx-runtime";
12
- import { useI18n as x } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
5
+ import { useGetApplicationQuery as i } from "../../generated/global-operations.js";
6
+ import { PermissionGuard as a } from "../components/PermissionGuard.js";
7
+ import { StoreImage as o, StoreImagePlaceholder as s } from "../components/StoreImage.js";
8
+ import { useEffect as c } from "react";
9
+ import { Markdown as l } from "@burdenoff/fe-libs/shared/components";
10
+ import { CheckCircle as u, Download as d, ExternalLink as f, Eye as p, FileText as m, Globe as h, Loader2 as g, Shield as _, Star as v, Tag as y } from "lucide-react";
11
+ import { useParams as b } from "react-router";
12
+ import { jsx as x, jsxs as S } from "react/jsx-runtime";
13
+ import { useI18n as C } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
13
14
  // src/devportal/pages/ListingPreviewPage.tsx
14
- var S = {
15
+ var w = {
15
16
  FREE: "Free",
16
17
  FREEMIUM: "Free with in-app purchases",
17
18
  PAID: "Paid",
@@ -19,7 +20,7 @@ var S = {
19
20
  SUBSCRIPTION: "Subscription",
20
21
  USAGE_BASED: "Usage-based pricing",
21
22
  ENTERPRISE: "Enterprise pricing"
22
- }, C = {
23
+ }, T = {
23
24
  WORKFLOW: "Workflow",
24
25
  WIDGET: "Widget",
25
26
  BOT: "Bot / Chatbot",
@@ -34,329 +35,332 @@ var S = {
34
35
  DESKTOP_APP: "Desktop App",
35
36
  CLI_TOOL: "CLI Tool",
36
37
  SERVICE: "Service"
37
- }, w = () => {
38
- let { appId: w } = v(), { navigate: T, basePath: E } = r(), { t: D } = x(), O = (e, t) => {
39
- let n = D(e);
38
+ }, E = () => {
39
+ let { appId: E } = b(), { navigate: D, basePath: O } = r(), { t: k } = C(), A = (e, t) => {
40
+ let n = k(e);
40
41
  return n === e ? t : n;
41
- }, { data: k, loading: A, error: j } = a({
42
- variables: { id: w },
43
- skip: !w,
42
+ }, { data: j, loading: M, error: N } = i({
43
+ variables: { id: E },
44
+ skip: !E,
44
45
  fetchPolicy: "cache-and-network"
45
- }), M = k?.application;
46
- if (o(() => {
47
- let e = M?.name;
48
- if (!w || !e) return;
46
+ }), P = j?.application;
47
+ if (c(() => {
48
+ let e = P?.name;
49
+ if (!E || !e) return;
49
50
  let t = window.__breadcrumbRegistry;
50
- return t?.register(w, e), () => t?.unregister(w);
51
- }, [w, M?.name]), A) return /* @__PURE__ */ y(e, {
52
- title: O("devportal.marketplacePreview", "Marketplace Preview"),
53
- description: O("devportal.loading", "Loading..."),
54
- backLink: `/apps/${w}`,
55
- backLabel: O("devportal.backToApplication", "Back to Application"),
56
- children: /* @__PURE__ */ y("div", {
51
+ return t?.register(E, e), () => t?.unregister(E);
52
+ }, [E, P?.name]), M) return /* @__PURE__ */ x(e, {
53
+ title: A("devportal.marketplacePreview", "Marketplace Preview"),
54
+ description: A("devportal.loading", "Loading..."),
55
+ backLink: `/apps/${E}`,
56
+ backLabel: A("devportal.backToApplication", "Back to Application"),
57
+ children: /* @__PURE__ */ x("div", {
57
58
  className: "flex items-center justify-center py-12",
58
- children: /* @__PURE__ */ y(m, { className: "h-8 w-8 animate-spin text-text-secondary" })
59
+ children: /* @__PURE__ */ x(g, { className: "h-8 w-8 animate-spin text-text-secondary" })
59
60
  })
60
61
  });
61
- if (j || !M) return /* @__PURE__ */ y(e, {
62
- title: O("devportal.marketplacePreview", "Marketplace Preview"),
63
- description: O("devportal.couldNotLoadApplication", "Could not load application"),
64
- backLink: `/apps/${w}`,
65
- backLabel: O("devportal.backToApplication", "Back to Application"),
66
- children: /* @__PURE__ */ y(n, {
62
+ if (N || !P) return /* @__PURE__ */ x(e, {
63
+ title: A("devportal.marketplacePreview", "Marketplace Preview"),
64
+ description: A("devportal.couldNotLoadApplication", "Could not load application"),
65
+ backLink: `/apps/${E}`,
66
+ backLabel: A("devportal.backToApplication", "Back to Application"),
67
+ children: /* @__PURE__ */ x(n, {
67
68
  variant: "error",
68
- title: O("devportal.failedToLoadApplication", "Failed to load application"),
69
- children: j?.message ?? O("devportal.applicationNotFound", "Application not found")
69
+ title: A("devportal.failedToLoadApplication", "Failed to load application"),
70
+ children: N?.message ?? A("devportal.applicationNotFound", "Application not found")
70
71
  })
71
72
  });
72
- let N = Array.isArray(M.screenshots) ? M.screenshots : [], P = M.status === "PUBLISHED";
73
- return /* @__PURE__ */ y(i, {
73
+ let F = Array.isArray(P.screenshots) ? P.screenshots : [], I = P.status === "PUBLISHED";
74
+ return /* @__PURE__ */ x(a, {
74
75
  authOnly: !0,
75
- children: /* @__PURE__ */ b(e, {
76
- title: O("devportal.marketplacePreview", "Marketplace Preview"),
77
- description: O("devportal.marketplacePreviewDescription", "Preview how your app will appear in the marketplace"),
78
- purpose: O("devportal.marketplacePreviewPurpose", "See exactly how shoppers will experience your store listing — icon, screenshots, description, and pricing — before it goes live. Use it to catch missing assets or typos, then submit for review when the listing looks right."),
79
- backLink: `/apps/${w}`,
80
- backLabel: O("devportal.backToApplication", "Back to Application"),
81
- actions: P ? void 0 : /* @__PURE__ */ b("button", {
82
- onClick: () => T?.(`${E}/apps/${w}/publish`),
76
+ children: /* @__PURE__ */ S(e, {
77
+ title: A("devportal.marketplacePreview", "Marketplace Preview"),
78
+ description: A("devportal.marketplacePreviewDescription", "Preview how your app will appear in the marketplace"),
79
+ purpose: A("devportal.marketplacePreviewPurpose", "See exactly how shoppers will experience your store listing — icon, screenshots, description, and pricing — before it goes live. Use it to catch missing assets or typos, then submit for review when the listing looks right."),
80
+ backLink: `/apps/${E}`,
81
+ backLabel: A("devportal.backToApplication", "Back to Application"),
82
+ actions: I ? void 0 : /* @__PURE__ */ S("button", {
83
+ onClick: () => D?.(`${O}/apps/${E}/publish`),
83
84
  className: "inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
84
- children: [/* @__PURE__ */ y(d, { size: 16 }), O("devportal.submitForReview", "Submit for Review")]
85
+ children: [/* @__PURE__ */ x(p, { size: 16 }), A("devportal.submitForReview", "Submit for Review")]
85
86
  }),
86
87
  children: [
87
- /* @__PURE__ */ b("div", {
88
+ /* @__PURE__ */ S("div", {
88
89
  className: "flex items-center gap-2 rounded-lg border border-border-subtle bg-status-warning-bg-subtle px-4 py-3 text-sm text-status-warning-text",
89
- children: [/* @__PURE__ */ y(d, {
90
+ children: [/* @__PURE__ */ x(p, {
90
91
  size: 16,
91
92
  className: "flex-shrink-0"
92
- }), /* @__PURE__ */ y("span", { children: O("devportal.previewBannerText", "This is a preview of your marketplace listing. It shows how your app will appear to users after publication.") })]
93
+ }), /* @__PURE__ */ x("span", { children: A("devportal.previewBannerText", "This is a preview of your marketplace listing. It shows how your app will appear to users after publication.") })]
93
94
  }),
94
- /* @__PURE__ */ b("div", {
95
+ /* @__PURE__ */ S("div", {
95
96
  className: "rounded-xl border bg-bg-surface overflow-hidden",
96
97
  children: [
97
- M.bannerUrl ? /* @__PURE__ */ y("div", {
98
- className: "h-48 w-full overflow-hidden",
99
- children: /* @__PURE__ */ y("img", {
100
- src: M.bannerUrl,
101
- alt: O("devportal.appBannerAlt", "App banner"),
102
- className: "h-full w-full object-cover"
103
- })
104
- }) : /* @__PURE__ */ y("div", { className: "h-32 w-full bg-gradient-to-r from-primary/20 to-primary/5" }),
105
- /* @__PURE__ */ y("div", {
98
+ /* @__PURE__ */ x(o, {
99
+ src: P.bannerUrl,
100
+ alt: A("devportal.appBannerAlt", "App banner"),
101
+ className: "block h-48 w-full object-cover",
102
+ fallback: /* @__PURE__ */ x("div", { className: "h-32 w-full bg-gradient-to-r from-primary/20 to-primary/5" })
103
+ }),
104
+ /* @__PURE__ */ x("div", {
106
105
  className: "p-6",
107
- children: /* @__PURE__ */ b("div", {
106
+ children: /* @__PURE__ */ S("div", {
108
107
  className: "flex items-start gap-5",
109
108
  children: [
110
- M.iconUrl ? /* @__PURE__ */ y("img", {
111
- src: M.iconUrl,
112
- alt: M.name,
113
- className: "h-20 w-20 rounded-2xl border object-cover flex-shrink-0 shadow-sm"
114
- }) : /* @__PURE__ */ y("div", {
115
- className: "h-20 w-20 rounded-2xl border bg-bg-sunken flex items-center justify-center flex-shrink-0",
116
- children: /* @__PURE__ */ y("span", {
117
- className: "text-3xl font-bold text-text-secondary",
118
- "aria-label": O("devportal.appIconFallbackAriaLabel", "App icon"),
119
- children: M.name.charAt(0).toUpperCase()
109
+ /* @__PURE__ */ x(o, {
110
+ src: P.iconUrl,
111
+ alt: P.name,
112
+ className: "h-20 w-20 rounded-2xl border object-cover flex-shrink-0 shadow-sm",
113
+ fallback: /* @__PURE__ */ x("div", {
114
+ className: "h-20 w-20 rounded-2xl border bg-bg-sunken flex items-center justify-center flex-shrink-0",
115
+ children: /* @__PURE__ */ x("span", {
116
+ className: "text-3xl font-bold text-text-secondary",
117
+ "aria-label": A("devportal.appIconFallbackAriaLabel", "App icon"),
118
+ children: P.name.charAt(0).toUpperCase()
119
+ })
120
120
  })
121
121
  }),
122
- /* @__PURE__ */ b("div", {
122
+ /* @__PURE__ */ S("div", {
123
123
  className: "flex-1 min-w-0",
124
124
  children: [
125
- /* @__PURE__ */ b("div", {
125
+ /* @__PURE__ */ S("div", {
126
126
  className: "flex flex-wrap items-center gap-2",
127
127
  children: [
128
- /* @__PURE__ */ y("h1", {
128
+ /* @__PURE__ */ x("h1", {
129
129
  className: "text-2xl font-bold",
130
- children: M.name
130
+ children: P.name
131
131
  }),
132
- M.isVerified && /* @__PURE__ */ y(c, {
132
+ P.isVerified && /* @__PURE__ */ x(u, {
133
133
  size: 20,
134
134
  className: "text-primary"
135
135
  }),
136
- M.isFeatured && /* @__PURE__ */ y("span", {
136
+ P.isFeatured && /* @__PURE__ */ x("span", {
137
137
  className: "rounded-full bg-status-warning-bg-subtle px-2 py-0.5 text-xs font-medium text-status-warning-text",
138
- children: O("devportal.featured", "Featured")
138
+ children: A("devportal.featured", "Featured")
139
139
  })
140
140
  ]
141
141
  }),
142
- /* @__PURE__ */ y("p", {
142
+ /* @__PURE__ */ x("p", {
143
143
  className: "mt-1 text-text-secondary",
144
- children: M.shortDescription ?? M.description ?? O("devportal.noDescription", "No description")
144
+ children: P.shortDescription ?? P.description ?? A("devportal.noDescription", "No description")
145
145
  }),
146
- /* @__PURE__ */ b("div", {
146
+ /* @__PURE__ */ S("div", {
147
147
  className: "mt-3 flex flex-wrap items-center gap-4 text-sm text-text-secondary",
148
148
  children: [
149
- M.averageRating != null && /* @__PURE__ */ b("div", {
149
+ P.averageRating != null && /* @__PURE__ */ S("div", {
150
150
  className: "flex items-center gap-1",
151
151
  children: [
152
- /* @__PURE__ */ y(g, {
152
+ /* @__PURE__ */ x(v, {
153
153
  size: 14,
154
154
  className: "text-status-warning-text fill-status-warning-text"
155
155
  }),
156
- /* @__PURE__ */ y("span", {
156
+ /* @__PURE__ */ x("span", {
157
157
  className: "font-medium text-text-primary",
158
- children: M.averageRating.toFixed(1)
158
+ children: P.averageRating.toFixed(1)
159
159
  }),
160
- /* @__PURE__ */ b("span", { children: [
160
+ /* @__PURE__ */ S("span", { children: [
161
161
  "(",
162
- M.reviewCount ?? 0,
162
+ P.reviewCount ?? 0,
163
163
  " ",
164
- O("devportal.reviews", "reviews"),
164
+ A("devportal.reviews", "reviews"),
165
165
  ")"
166
166
  ] })
167
167
  ]
168
168
  }),
169
- /* @__PURE__ */ b("div", {
169
+ /* @__PURE__ */ S("div", {
170
170
  className: "flex items-center gap-1",
171
- children: [/* @__PURE__ */ y(l, { size: 14 }), /* @__PURE__ */ b("span", { children: [
172
- (M.installCount ?? 0).toLocaleString(),
171
+ children: [/* @__PURE__ */ x(d, { size: 14 }), /* @__PURE__ */ S("span", { children: [
172
+ (P.installCount ?? 0).toLocaleString(),
173
173
  " ",
174
- O("devportal.installs", "installs")
174
+ A("devportal.installs", "installs")
175
175
  ] })]
176
176
  }),
177
- M.category && /* @__PURE__ */ y("span", {
177
+ P.category && /* @__PURE__ */ x("span", {
178
178
  className: "rounded-full border px-2 py-0.5 text-xs",
179
- children: M.category
179
+ children: P.category
180
180
  }),
181
- /* @__PURE__ */ y("span", {
181
+ /* @__PURE__ */ x("span", {
182
182
  className: "rounded-full border px-2 py-0.5 text-xs",
183
- children: C[M.appType] ?? M.appType
183
+ children: T[P.appType] ?? P.appType
184
184
  })
185
185
  ]
186
186
  })
187
187
  ]
188
188
  }),
189
- /* @__PURE__ */ b("div", {
189
+ /* @__PURE__ */ S("div", {
190
190
  className: "flex-shrink-0 text-right space-y-2",
191
191
  children: [
192
- /* @__PURE__ */ y("div", {
192
+ /* @__PURE__ */ x("div", {
193
193
  className: "text-lg font-semibold",
194
- children: S[M.pricingType ?? "FREE"] ?? "Free"
194
+ children: w[P.pricingType ?? "FREE"] ?? "Free"
195
195
  }),
196
- /* @__PURE__ */ y("button", {
196
+ /* @__PURE__ */ x("button", {
197
197
  disabled: !0,
198
198
  className: "w-full rounded-lg bg-action-primary-bg px-6 py-2 text-sm font-semibold text-action-primary-text opacity-60 cursor-not-allowed",
199
- title: O("devportal.previewOnly", "Preview only"),
200
- children: O("devportal.install", "Install")
199
+ title: A("devportal.previewOnly", "Preview only"),
200
+ children: A("devportal.install", "Install")
201
201
  }),
202
- /* @__PURE__ */ y("p", {
202
+ /* @__PURE__ */ x("p", {
203
203
  className: "text-xs text-text-secondary",
204
- children: O("devportal.previewOnly", "Preview only")
204
+ children: A("devportal.previewOnly", "Preview only")
205
205
  })
206
206
  ]
207
207
  })
208
208
  ]
209
209
  })
210
210
  }),
211
- N.length > 0 && /* @__PURE__ */ b("div", {
211
+ F.length > 0 && /* @__PURE__ */ S("div", {
212
212
  className: "border-t px-6 py-5",
213
- children: [/* @__PURE__ */ y("h2", {
213
+ children: [/* @__PURE__ */ x("h2", {
214
214
  className: "text-base font-semibold mb-3",
215
- children: O("devportal.screenshots", "Screenshots")
216
- }), /* @__PURE__ */ y("div", {
215
+ children: A("devportal.screenshots", "Screenshots")
216
+ }), /* @__PURE__ */ x("div", {
217
217
  className: "flex gap-3 overflow-x-auto pb-2",
218
- children: N.map((e, t) => /* @__PURE__ */ y("img", {
218
+ children: F.map((e, t) => /* @__PURE__ */ x(o, {
219
219
  src: e,
220
- alt: `${O("devportal.screenshotAlt", "Screenshot")} ${t + 1}`,
221
- className: "h-44 w-auto rounded-lg border object-cover flex-shrink-0"
220
+ alt: `${A("devportal.screenshotAlt", "Screenshot")} ${t + 1}`,
221
+ className: "h-44 w-auto rounded-lg border object-cover flex-shrink-0",
222
+ fallback: /* @__PURE__ */ x(s, {
223
+ className: "h-44 w-72 rounded-lg",
224
+ iconSize: 24
225
+ })
222
226
  }, t))
223
227
  })]
224
228
  }),
225
- /* @__PURE__ */ b("div", {
229
+ /* @__PURE__ */ S("div", {
226
230
  className: "border-t px-6 py-5",
227
- children: [/* @__PURE__ */ y("h2", {
231
+ children: [/* @__PURE__ */ x("h2", {
228
232
  className: "text-base font-semibold mb-2",
229
- children: O("devportal.about", "About")
230
- }), M.description || M.shortDescription ? /* @__PURE__ */ y(s, {
233
+ children: A("devportal.about", "About")
234
+ }), P.description || P.shortDescription ? /* @__PURE__ */ x(l, {
231
235
  className: "text-sm text-text-secondary",
232
- children: M.description ?? M.shortDescription ?? ""
233
- }) : /* @__PURE__ */ y("p", {
236
+ children: P.description ?? P.shortDescription ?? ""
237
+ }) : /* @__PURE__ */ x("p", {
234
238
  className: "text-sm text-text-secondary",
235
- children: O("devportal.noDetailedDescription", "No detailed description provided.")
239
+ children: A("devportal.noDetailedDescription", "No detailed description provided.")
236
240
  })]
237
241
  }),
238
- Array.isArray(M.tags) && M.tags.length > 0 && /* @__PURE__ */ y("div", {
242
+ Array.isArray(P.tags) && P.tags.length > 0 && /* @__PURE__ */ x("div", {
239
243
  className: "border-t px-6 py-4",
240
- children: /* @__PURE__ */ y("div", {
244
+ children: /* @__PURE__ */ x("div", {
241
245
  className: "flex flex-wrap gap-2",
242
- children: M.tags.map((e) => /* @__PURE__ */ b("span", {
246
+ children: P.tags.map((e) => /* @__PURE__ */ S("span", {
243
247
  className: "inline-flex items-center gap-1 rounded-full border px-3 py-1 text-xs text-text-secondary",
244
- children: [/* @__PURE__ */ y(_, { size: 10 }), e]
248
+ children: [/* @__PURE__ */ x(y, { size: 10 }), e]
245
249
  }, e))
246
250
  })
247
251
  }),
248
- /* @__PURE__ */ b("div", {
252
+ /* @__PURE__ */ S("div", {
249
253
  className: "border-t px-6 py-5 grid grid-cols-1 sm:grid-cols-2 gap-4 text-sm",
250
254
  children: [
251
- M.websiteUrl && /* @__PURE__ */ b("a", {
252
- href: M.websiteUrl,
255
+ P.websiteUrl && /* @__PURE__ */ S("a", {
256
+ href: P.websiteUrl,
253
257
  target: "_blank",
254
258
  rel: "noopener noreferrer",
255
259
  className: "flex items-center gap-2 text-primary hover:underline",
256
260
  children: [
257
- /* @__PURE__ */ y(p, { size: 14 }),
258
- O("devportal.website", "Website"),
259
- /* @__PURE__ */ y(u, { size: 12 })
261
+ /* @__PURE__ */ x(h, { size: 14 }),
262
+ A("devportal.website", "Website"),
263
+ /* @__PURE__ */ x(f, { size: 12 })
260
264
  ]
261
265
  }),
262
- M.documentationUrl && /* @__PURE__ */ b("a", {
263
- href: M.documentationUrl,
266
+ P.documentationUrl && /* @__PURE__ */ S("a", {
267
+ href: P.documentationUrl,
264
268
  target: "_blank",
265
269
  rel: "noopener noreferrer",
266
270
  className: "flex items-center gap-2 text-primary hover:underline",
267
271
  children: [
268
- /* @__PURE__ */ y(f, { size: 14 }),
269
- O("devportal.documentation", "Documentation"),
270
- /* @__PURE__ */ y(u, { size: 12 })
272
+ /* @__PURE__ */ x(m, { size: 14 }),
273
+ A("devportal.documentation", "Documentation"),
274
+ /* @__PURE__ */ x(f, { size: 12 })
271
275
  ]
272
276
  }),
273
- M.privacyPolicyUrl && /* @__PURE__ */ b("a", {
274
- href: M.privacyPolicyUrl,
277
+ P.privacyPolicyUrl && /* @__PURE__ */ S("a", {
278
+ href: P.privacyPolicyUrl,
275
279
  target: "_blank",
276
280
  rel: "noopener noreferrer",
277
281
  className: "flex items-center gap-2 text-primary hover:underline",
278
282
  children: [
279
- /* @__PURE__ */ y(h, { size: 14 }),
280
- O("devportal.privacyPolicy", "Privacy Policy"),
281
- /* @__PURE__ */ y(u, { size: 12 })
283
+ /* @__PURE__ */ x(_, { size: 14 }),
284
+ A("devportal.privacyPolicy", "Privacy Policy"),
285
+ /* @__PURE__ */ x(f, { size: 12 })
282
286
  ]
283
287
  }),
284
- M.termsOfServiceUrl && /* @__PURE__ */ b("a", {
285
- href: M.termsOfServiceUrl,
288
+ P.termsOfServiceUrl && /* @__PURE__ */ S("a", {
289
+ href: P.termsOfServiceUrl,
286
290
  target: "_blank",
287
291
  rel: "noopener noreferrer",
288
292
  className: "flex items-center gap-2 text-primary hover:underline",
289
293
  children: [
290
- /* @__PURE__ */ y(f, { size: 14 }),
291
- O("devportal.termsOfService", "Terms of Service"),
292
- /* @__PURE__ */ y(u, { size: 12 })
294
+ /* @__PURE__ */ x(m, { size: 14 }),
295
+ A("devportal.termsOfService", "Terms of Service"),
296
+ /* @__PURE__ */ x(f, { size: 12 })
293
297
  ]
294
298
  })
295
299
  ]
296
300
  })
297
301
  ]
298
302
  }),
299
- /* @__PURE__ */ b(t, {
300
- title: O("devportal.listingCompleteness", "Listing Completeness"),
301
- children: [/* @__PURE__ */ y("div", {
303
+ /* @__PURE__ */ S(t, {
304
+ title: A("devportal.listingCompleteness", "Listing Completeness"),
305
+ children: [/* @__PURE__ */ x("div", {
302
306
  className: "space-y-2",
303
307
  children: [
304
308
  {
305
- label: O("devportal.completenessAppIcon", "App icon"),
306
- ok: !!M.iconUrl
309
+ label: A("devportal.completenessAppIcon", "App icon"),
310
+ ok: !!P.iconUrl
307
311
  },
308
312
  {
309
- label: O("devportal.completenessBannerImage", "Banner image"),
310
- ok: !!M.bannerUrl
313
+ label: A("devportal.completenessBannerImage", "Banner image"),
314
+ ok: !!P.bannerUrl
311
315
  },
312
316
  {
313
- label: O("devportal.completenessShortDescription", "Short description"),
314
- ok: !!M.shortDescription
317
+ label: A("devportal.completenessShortDescription", "Short description"),
318
+ ok: !!P.shortDescription
315
319
  },
316
320
  {
317
- label: O("devportal.completenessFullDescription", "Full description"),
318
- ok: !!M.description
321
+ label: A("devportal.completenessFullDescription", "Full description"),
322
+ ok: !!P.description
319
323
  },
320
324
  {
321
- label: O("devportal.completenessScreenshots", "Screenshots (3+)"),
322
- ok: N.length >= 3
325
+ label: A("devportal.completenessScreenshots", "Screenshots (3+)"),
326
+ ok: F.length >= 3
323
327
  },
324
328
  {
325
- label: O("devportal.completenessCategory", "Category"),
326
- ok: !!M.category
329
+ label: A("devportal.completenessCategory", "Category"),
330
+ ok: !!P.category
327
331
  },
328
332
  {
329
- label: O("devportal.completenessTags", "Tags"),
330
- ok: Array.isArray(M.tags) && M.tags.length > 0
333
+ label: A("devportal.completenessTags", "Tags"),
334
+ ok: Array.isArray(P.tags) && P.tags.length > 0
331
335
  },
332
336
  {
333
- label: O("devportal.completenessPrivacyPolicy", "Privacy policy URL"),
334
- ok: !!M.privacyPolicyUrl
337
+ label: A("devportal.completenessPrivacyPolicy", "Privacy policy URL"),
338
+ ok: !!P.privacyPolicyUrl
335
339
  },
336
340
  {
337
- label: O("devportal.completenessTermsOfService", "Terms of service URL"),
338
- ok: !!M.termsOfServiceUrl
341
+ label: A("devportal.completenessTermsOfService", "Terms of service URL"),
342
+ ok: !!P.termsOfServiceUrl
339
343
  }
340
- ].map(({ label: e, ok: t }) => /* @__PURE__ */ b("div", {
344
+ ].map(({ label: e, ok: t }) => /* @__PURE__ */ S("div", {
341
345
  className: "flex items-center gap-3 text-sm",
342
- children: [t ? /* @__PURE__ */ y(c, {
346
+ children: [t ? /* @__PURE__ */ x(u, {
343
347
  size: 16,
344
348
  className: "text-status-success-text flex-shrink-0"
345
- }) : /* @__PURE__ */ y("div", { className: "h-4 w-4 rounded-full border-2 border-muted-foreground flex-shrink-0" }), /* @__PURE__ */ y("span", {
349
+ }) : /* @__PURE__ */ x("div", { className: "h-4 w-4 rounded-full border-2 border-muted-foreground flex-shrink-0" }), /* @__PURE__ */ x("span", {
346
350
  className: t ? "text-text-primary" : "text-text-secondary",
347
351
  children: e
348
352
  })]
349
353
  }, e))
350
- }), !P && /* @__PURE__ */ y("button", {
351
- onClick: () => T?.(`${E}/apps/${w}/edit`),
354
+ }), !I && /* @__PURE__ */ x("button", {
355
+ onClick: () => D?.(`${O}/apps/${E}/edit`),
352
356
  className: "mt-4 rounded-md border px-3 py-1.5 text-sm hover:bg-bg-sunken",
353
- children: O("devportal.editToImproveListing", "Edit to improve listing →")
357
+ children: A("devportal.editToImproveListing", "Edit to improve listing →")
354
358
  })]
355
359
  })
356
360
  ]
357
361
  })
358
362
  });
359
363
  };
360
- export { w as ListingPreviewPage };
364
+ export { E as ListingPreviewPage };
361
365
 
362
366
  //# sourceMappingURL=ListingPreviewPage.js.map