@burdenoff/microfe-devportal 2026.828.1 → 2026.830.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 (104) hide show
  1. package/dist/devportal/AdminDevportalRoot.d.ts.map +1 -1
  2. package/dist/devportal/AdminDevportalRoot.js +16 -19
  3. package/dist/devportal/AdminDevportalRoot.js.map +1 -1
  4. package/dist/devportal/DevportalRoot.d.ts.map +1 -1
  5. package/dist/devportal/DevportalRoot.js +36 -39
  6. package/dist/devportal/DevportalRoot.js.map +1 -1
  7. package/dist/devportal/components/AppCard.js +41 -41
  8. package/dist/devportal/components/ConfirmDialog.d.ts.map +1 -1
  9. package/dist/devportal/components/ConfirmDialog.js +19 -22
  10. package/dist/devportal/components/ConfirmDialog.js.map +1 -1
  11. package/dist/devportal/components/DataTable.d.ts.map +1 -1
  12. package/dist/devportal/components/DataTable.js +31 -34
  13. package/dist/devportal/components/DataTable.js.map +1 -1
  14. package/dist/devportal/components/FeatureFlaggedRoute.js +8 -8
  15. package/dist/devportal/components/FormField.d.ts.map +1 -1
  16. package/dist/devportal/components/FormField.js +26 -32
  17. package/dist/devportal/components/FormField.js.map +1 -1
  18. package/dist/devportal/components/GrantDelegationModal.js +64 -64
  19. package/dist/devportal/components/GrantDelegationModal.js.map +1 -1
  20. package/dist/devportal/components/LoadingState.d.ts.map +1 -1
  21. package/dist/devportal/components/LoadingState.js +5 -8
  22. package/dist/devportal/components/LoadingState.js.map +1 -1
  23. package/dist/devportal/components/PageLayout.d.ts.map +1 -1
  24. package/dist/devportal/components/PageLayout.js +10 -13
  25. package/dist/devportal/components/PageLayout.js.map +1 -1
  26. package/dist/devportal/components/PermissionGuard.d.ts.map +1 -1
  27. package/dist/devportal/components/PermissionGuard.js +11 -14
  28. package/dist/devportal/components/PermissionGuard.js.map +1 -1
  29. package/dist/devportal/components/SecretDisplay.d.ts.map +1 -1
  30. package/dist/devportal/components/SecretDisplay.js +24 -30
  31. package/dist/devportal/components/SecretDisplay.js.map +1 -1
  32. package/dist/devportal/components/SectionNav.d.ts.map +1 -1
  33. package/dist/devportal/components/SectionNav.js +24 -27
  34. package/dist/devportal/components/SectionNav.js.map +1 -1
  35. package/dist/devportal/components/StatusBadge.d.ts.map +1 -1
  36. package/dist/devportal/components/StatusBadge.js +24 -33
  37. package/dist/devportal/components/StatusBadge.js.map +1 -1
  38. package/dist/devportal/index.d.ts +1 -0
  39. package/dist/devportal/index.d.ts.map +1 -1
  40. package/dist/devportal/index.js +1 -0
  41. package/dist/devportal/pages/AdminReviewPage.js +172 -172
  42. package/dist/devportal/pages/AnalyticsDashboardPage.js +43 -43
  43. package/dist/devportal/pages/AnalyticsDashboardPage.js.map +1 -1
  44. package/dist/devportal/pages/ApiKeysPage.js +119 -119
  45. package/dist/devportal/pages/ApiKeysPage.js.map +1 -1
  46. package/dist/devportal/pages/AppLogsPage.js +45 -45
  47. package/dist/devportal/pages/ApplicationDetailPage.js +607 -607
  48. package/dist/devportal/pages/ApplicationVersionsPage.js +13 -13
  49. package/dist/devportal/pages/ApplicationsPage.d.ts.map +1 -1
  50. package/dist/devportal/pages/ApplicationsPage.js +104 -101
  51. package/dist/devportal/pages/ApplicationsPage.js.map +1 -1
  52. package/dist/devportal/pages/CreateApiKeyPage.js +45 -45
  53. package/dist/devportal/pages/CreateApplicationPage.js +38 -38
  54. package/dist/devportal/pages/CreateApplicationPage.js.map +1 -1
  55. package/dist/devportal/pages/CreateOAuthClientPage.js +52 -52
  56. package/dist/devportal/pages/CreateOrganizationPage.js +26 -26
  57. package/dist/devportal/pages/CreateWebhookPage.d.ts.map +1 -1
  58. package/dist/devportal/pages/CreateWebhookPage.js +48 -48
  59. package/dist/devportal/pages/CreateWebhookPage.js.map +1 -1
  60. package/dist/devportal/pages/DashboardPage.d.ts.map +1 -1
  61. package/dist/devportal/pages/DashboardPage.js +66 -72
  62. package/dist/devportal/pages/DashboardPage.js.map +1 -1
  63. package/dist/devportal/pages/DelegationsPage.js +174 -174
  64. package/dist/devportal/pages/DocumentationPage.js +93 -93
  65. package/dist/devportal/pages/EditApplicationPage.js +14 -14
  66. package/dist/devportal/pages/EditApplicationPage.js.map +1 -1
  67. package/dist/devportal/pages/ListingPreviewPage.js +76 -76
  68. package/dist/devportal/pages/OAuthClientDetailPage.js +75 -75
  69. package/dist/devportal/pages/OAuthClientDetailPage.js.map +1 -1
  70. package/dist/devportal/pages/OAuthClientsPage.js +64 -64
  71. package/dist/devportal/pages/OrganizationDetailPage.js +189 -189
  72. package/dist/devportal/pages/OrganizationDetailPage.js.map +1 -1
  73. package/dist/devportal/pages/OrganizationMembersPage.js +10 -10
  74. package/dist/devportal/pages/OrganizationsPage.d.ts.map +1 -1
  75. package/dist/devportal/pages/OrganizationsPage.js +163 -154
  76. package/dist/devportal/pages/OrganizationsPage.js.map +1 -1
  77. package/dist/devportal/pages/PublishPage.js +104 -104
  78. package/dist/devportal/pages/PublishPage.js.map +1 -1
  79. package/dist/devportal/pages/PublisherProfilePage.js +55 -55
  80. package/dist/devportal/pages/ResourcesPage.js +60 -60
  81. package/dist/devportal/pages/RevenueDashboardPage.js +60 -60
  82. package/dist/devportal/pages/RevenueDashboardPage.js.map +1 -1
  83. package/dist/devportal/pages/SellerDashboardPage.js +83 -83
  84. package/dist/devportal/pages/SellerItemsPage.js +163 -163
  85. package/dist/devportal/pages/SellerItemsPage.js.map +1 -1
  86. package/dist/devportal/pages/SellerOrdersPage.js +63 -63
  87. package/dist/devportal/pages/SettingsPage.js +21 -21
  88. package/dist/devportal/pages/SetupPage.js +183 -183
  89. package/dist/devportal/pages/SetupPage.js.map +1 -1
  90. package/dist/devportal/pages/StoreSubmissionPage.js +5 -5
  91. package/dist/devportal/pages/WebhookDetailPage.js +123 -123
  92. package/dist/devportal/pages/WebhookDetailPage.js.map +1 -1
  93. package/dist/devportal/pages/WebhooksPage.js +118 -118
  94. package/dist/devportal/pages/WebhooksPage.js.map +1 -1
  95. package/dist/devportal/utils/i18n.d.ts +9 -2
  96. package/dist/devportal/utils/i18n.d.ts.map +1 -1
  97. package/dist/devportal/utils/i18n.js +13 -10
  98. package/dist/devportal/utils/i18n.js.map +1 -1
  99. package/dist/index.js +2 -1
  100. package/dist/translations/en.d.ts +1251 -0
  101. package/dist/translations/en.d.ts.map +1 -0
  102. package/dist/translations/en.js +1235 -0
  103. package/dist/translations/en.js.map +1 -0
  104. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"PublishPage.js","names":[],"sources":["../../../src/devportal/pages/PublishPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useEffect, useState, useMemo } from \"react\";\nimport { useParams } from \"react-router\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n CheckCircle,\n XCircle,\n AlertTriangle,\n Send,\n FileText,\n Shield,\n Image,\n Globe,\n Loader2,\n Eye,\n ArrowRight,\n PartyPopper,\n Link,\n Webhook,\n KeyRound,\n} from \"lucide-react\";\nimport { gql } from \"@apollo/client\";\nimport { useQuery } from \"@apollo/client/react\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { Alert } from \"../components/ConfirmDialog\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport { DEVPORTAL_PERMISSIONS } from \"../constants/permissions\";\nimport {\n useGetApplicationQuery,\n useSubmitApplicationMutation,\n useSubmitApplicationForReviewMutation,\n} from \"../../generated/global-operations\";\nimport { useDevportalPermission } from \"../hooks\";\n\nconst MY_PUBLISHER_QUERY = gql`\n query PublishPagePublisher {\n myPublisher {\n id\n }\n }\n`;\nconst PUBLISHER_PRODUCTS_QUERY = gql`\n query PublishPageProducts($publisherId: String!) {\n products(filter: { publisherId: $publisherId }) {\n id\n productId\n }\n }\n`;\nconst APP_WEBHOOKS_QUERY = gql`\n query PublishPageWebhooks($applicationId: ID!) {\n webhooks(applicationId: $applicationId) {\n id\n }\n }\n`;\n\ninterface ChecklistItem {\n id: string;\n label: string;\n description: string;\n status: \"passed\" | \"failed\" | \"warning\" | \"pending\";\n icon: React.ReactNode;\n actionLabel?: string;\n actionPath?: string;\n}\n\nconst ALREADY_SUBMITTED_STATUSES = [\n \"SUBMITTED\",\n \"IN_REVIEW\",\n \"APPROVED\",\n \"PUBLISHED\",\n];\n\nexport const PublishPage: FC = () => {\n const { appId } = useParams<{ appId: string }>();\n const { navigate, basePath } = useDevportal();\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 [submitting, setSubmitting] = useState(false);\n const [submitError, setSubmitError] = useState<string | null>(null);\n const [submitted, setSubmitted] = useState(false);\n const [notes, setNotes] = useState(\"\");\n const submitPerm = useDevportalPermission(DEVPORTAL_PERMISSIONS.APP_SUBMIT);\n\n const {\n data,\n loading,\n error: queryError,\n } = useGetApplicationQuery({\n variables: { id: appId! },\n skip: !appId,\n fetchPolicy: \"network-only\",\n });\n\n const [submitApplication] = useSubmitApplicationMutation();\n const [submitApplicationForReview] = useSubmitApplicationForReviewMutation();\n\n // Two-step publisher lookup to find linked StoreProduct\n const { data: publisherData } = useQuery<{\n myPublisher: { id: string } | null;\n }>(MY_PUBLISHER_QUERY, { fetchPolicy: \"cache-first\" });\n const publisherId = publisherData?.myPublisher?.id ?? null;\n const { data: productsData } = useQuery<{\n products: { id: string; productId?: string | null }[];\n }>(PUBLISHER_PRODUCTS_QUERY, {\n variables: { publisherId: publisherId ?? \"\" },\n skip: !publisherId,\n fetchPolicy: \"cache-first\",\n });\n const linkedStoreProductId =\n productsData?.products?.find(\n (p: { id: string; productId?: string | null }) => p.productId === appId,\n )?.id ?? null;\n\n const isApiIntegration = data?.application?.appType === \"API_INTEGRATION\";\n const appManifest = data?.application?.manifest as\n | Record<string, unknown>\n | null\n | undefined;\n const appOauth = appManifest?.[\"oauth\"] as\n | Record<string, unknown>\n | undefined;\n const hasOAuthUrl = !!(\n appOauth?.[\"authorizationUrl\"] &&\n appOauth?.[\"tokenUrl\"] &&\n appOauth?.[\"clientId\"]\n );\n\n const { data: webhooksData } = useQuery<{ webhooks: { id: string }[] }>(\n APP_WEBHOOKS_QUERY,\n {\n variables: { applicationId: appId! },\n skip: !appId || !isApiIntegration,\n fetchPolicy: \"network-only\",\n },\n );\n const webhookCount = webhooksData?.webhooks?.length ?? 0;\n\n const app = data?.application;\n\n useEffect(() => {\n const name = app?.name;\n if (!appId || !name) return;\n const reg = (\n window as unknown as {\n __breadcrumbRegistry?: {\n register: (id: string, name: string) => void;\n unregister: (id: string) => void;\n };\n }\n ).__breadcrumbRegistry;\n reg?.register(appId, name);\n return () => reg?.unregister(appId);\n }, [appId, app?.name]);\n\n const isAlreadySubmitted = ALREADY_SUBMITTED_STATUSES.includes(\n app?.status ?? \"\",\n );\n\n const isPackageType = app?.appType === \"NODE\" || app?.appType === \"WORKFLOW\";\n const publishedVersionCount = app?.versions?.totalCount ?? 0;\n\n const checklist = useMemo((): ChecklistItem[] => {\n if (!app) return [];\n\n const screenshotCount = app.screenshots?.length ?? 0;\n\n const storeListingPath = `/apps/${appId}?tab=store-listing`;\n const versionsPath = `/apps/${appId}/versions`;\n const editPath = `/apps/${appId}/edit#oauth-config`;\n const webhooksPath = `/apps/${appId}/webhooks`;\n\n const items: ChecklistItem[] = [\n {\n id: \"name\",\n label: tr(\"devportal.checklistNameLabel\", \"Name & Short Description\"),\n description: tr(\n \"devportal.checklistNameDesc\",\n \"Name and short description are required for the store card\",\n ),\n status: app.name && app.shortDescription ? \"passed\" : \"failed\",\n icon: <FileText size={20} />,\n actionLabel: \"Edit store listing →\",\n actionPath: storeListingPath,\n },\n {\n id: \"category\",\n label: tr(\"devportal.checklistCategoryLabel\", \"Category\"),\n description: tr(\n \"devportal.checklistCategoryDesc\",\n \"A category helps users find your item in the marketplace\",\n ),\n status: app.category ? \"passed\" : \"failed\",\n icon: <Globe size={20} />,\n actionLabel: \"Edit app info →\",\n actionPath: `/apps/${appId}/edit`,\n },\n {\n id: \"privacy\",\n label: tr(\"devportal.checklistPrivacyLabel\", \"Privacy Policy\"),\n description: tr(\n \"devportal.checklistPrivacyDesc\",\n \"Privacy policy URL is required for store submission\",\n ),\n status: app.privacyPolicyUrl ? \"passed\" : \"failed\",\n icon: <Shield size={20} />,\n actionLabel: \"Edit store listing →\",\n actionPath: storeListingPath,\n },\n {\n id: \"terms\",\n label: tr(\"devportal.checklistTermsLabel\", \"Terms of Service\"),\n description: tr(\n \"devportal.checklistTermsDesc\",\n \"Terms of service URL is required for store submission\",\n ),\n status: app.termsOfServiceUrl ? \"passed\" : \"failed\",\n icon: <FileText size={20} />,\n actionLabel: \"Edit store listing →\",\n actionPath: storeListingPath,\n },\n {\n id: \"icon\",\n label: tr(\"devportal.checklistIconLabel\", \"App Icon\"),\n description: tr(\n \"devportal.checklistIconDesc\",\n \"An icon makes your listing stand out in the marketplace\",\n ),\n status: app.iconUrl ? \"passed\" : \"warning\",\n icon: <Image size={20} />,\n actionLabel: \"Edit store listing →\",\n actionPath: storeListingPath,\n },\n {\n id: \"screenshots\",\n label: tr(\"devportal.checklistScreenshotsLabel\", \"Screenshots\"),\n description: tr(\n \"devportal.checklistScreenshotsDesc\",\n \"At least 3 screenshots are recommended\",\n ),\n status:\n screenshotCount >= 3\n ? \"passed\"\n : screenshotCount > 0\n ? \"warning\"\n : \"warning\",\n icon: <Image size={20} />,\n actionLabel: \"Edit store listing →\",\n actionPath: storeListingPath,\n },\n ];\n\n if (isPackageType) {\n items.push({\n id: \"version\",\n label: tr(\"devportal.checklistVersionLabel\", \"Published Version\"),\n description: tr(\n \"devportal.checklistVersionDesc\",\n app?.appType === \"WORKFLOW\"\n ? \"At least one published version (manifest JSON) is required before submitting to the store\"\n : \"At least one published version (ZIP + manifest) is required before submitting to the store\",\n ),\n status: publishedVersionCount > 0 ? \"passed\" : \"failed\",\n icon: <CheckCircle size={20} />,\n actionLabel: \"Create a version →\",\n actionPath: versionsPath,\n });\n }\n\n if (app.appType === \"API_INTEGRATION\") {\n items.push({\n id: \"oauth\",\n label: tr(\"devportal.checklistOAuthLabel\", \"OAuth Configuration\"),\n description: tr(\n \"devportal.checklistOAuthDesc\",\n \"Authorization URL, Token URL and Client ID are required so users can connect their accounts. Without these the Connect button does not work.\",\n ),\n status: hasOAuthUrl ? \"passed\" : \"failed\",\n icon: <KeyRound size={20} />,\n actionLabel: \"Configure in Edit App →\",\n actionPath: editPath,\n });\n\n items.push({\n id: \"webhook\",\n label: tr(\"devportal.checklistWebhookLabel\", \"Webhook Endpoint\"),\n description: tr(\n \"devportal.checklistWebhookDesc\",\n \"At least one webhook endpoint must be configured so your server receives platform events after users connect. Without this the integration does nothing.\",\n ),\n status: webhookCount > 0 ? \"passed\" : \"failed\",\n icon: <Webhook size={20} />,\n actionLabel: \"Add a webhook →\",\n actionPath: webhooksPath,\n });\n\n items.push({\n id: \"documentation\",\n label: tr(\"devportal.checklistDocsLabel\", \"Documentation URL\"),\n description: tr(\n \"devportal.checklistDocsDesc\",\n \"Users need to know how to use and configure this integration. A documentation link is required for API integrations.\",\n ),\n status: app.documentationUrl ? \"passed\" : \"failed\",\n icon: <FileText size={20} />,\n actionLabel: \"Add documentation URL →\",\n actionPath: editPath,\n });\n\n items.push({\n id: \"website\",\n label: tr(\"devportal.checklistWebsiteLabel\", \"Website URL\"),\n description: tr(\n \"devportal.checklistWebsiteDesc\",\n \"Users need to verify who built this integration. A website URL is required so users know where to get support.\",\n ),\n status: app.websiteUrl ? \"passed\" : \"failed\",\n icon: <Link size={20} />,\n actionLabel: \"Add website URL →\",\n actionPath: editPath,\n });\n }\n\n items.push({\n id: \"status\",\n label: tr(\"devportal.checklistStatusLabel\", \"App Status\"),\n description: tr(\n \"devportal.checklistStatusDesc\",\n \"App must be in DRAFT or REJECTED state to submit\",\n ),\n status: [\"DRAFT\", \"REJECTED\"].includes(app.status ?? \"\")\n ? \"passed\"\n : \"warning\",\n icon: <CheckCircle size={20} />,\n });\n\n return items;\n }, [\n app,\n isPackageType,\n publishedVersionCount,\n webhookCount,\n hasOAuthUrl,\n appId,\n ]);\n\n const passedCount = checklist.filter((i) => i.status === \"passed\").length;\n const failedCount = checklist.filter((i) => i.status === \"failed\").length;\n const warningCount = checklist.filter((i) => i.status === \"warning\").length;\n const isSubmittableStatus = [\"DRAFT\", \"REJECTED\"].includes(app?.status ?? \"\");\n const canSubmit =\n !loading &&\n !queryError &&\n failedCount === 0 &&\n !!app &&\n !isAlreadySubmitted &&\n isSubmittableStatus;\n\n const getStatusIcon = (status: ChecklistItem[\"status\"]) => {\n switch (status) {\n case \"passed\":\n return <CheckCircle size={20} className=\"text-status-success-text\" />;\n case \"failed\":\n return <XCircle size={20} className=\"text-status-error-text\" />;\n case \"warning\":\n return <AlertTriangle size={20} className=\"text-status-warning-text\" />;\n default:\n return (\n <div className=\"h-5 w-5 rounded-full border-2 border-border-default\" />\n );\n }\n };\n\n const getStatusBg = (status: ChecklistItem[\"status\"]) => {\n switch (status) {\n case \"passed\":\n return \"bg-status-success-bg-subtle border-border-subtle\";\n case \"failed\":\n return \"bg-status-error-bg-subtle border-border-subtle\";\n case \"warning\":\n return \"bg-status-warning-bg-subtle border-border-subtle\";\n default:\n return \"bg-bg-canvas border-border-subtle\";\n }\n };\n\n const handleSubmit = async () => {\n if (!appId) return;\n setSubmitting(true);\n setSubmitError(null);\n try {\n // Submit Application for devportal review (sets Application.status = SUBMITTED)\n const result = await submitApplication({\n variables: { id: appId, notes: notes.trim() || undefined },\n });\n if (result.error) throw result.error;\n\n // Also submit ApplicationForReview to set StoreProduct.status = PENDING_REVIEW\n // so it appears in the store admin review queue at /store/dashboard/submissions\n await submitApplicationForReview({\n variables: { id: appId, notes: notes.trim() || undefined },\n });\n\n setSubmitted(true);\n } catch (err) {\n setSubmitError(\n err instanceof Error\n ? err.message\n : tr(\"devportal.submitFailedDefault\", \"Failed to submit for review\"),\n );\n } finally {\n setSubmitting(false);\n }\n };\n\n if (loading) {\n return (\n <PageLayout\n title={tr(\"devportal.publishToStoreTitle\", \"Publish to Store\")}\n description={tr(\n \"devportal.loadingApplicationDetails\",\n \"Loading application details...\",\n )}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n >\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"animate-spin h-8 w-8 text-text-secondary\" />\n </div>\n </PageLayout>\n );\n }\n\n if (queryError || !app) {\n return (\n <PageLayout\n title={tr(\"devportal.publishToStoreTitle\", \"Publish to Store\")}\n description={tr(\n \"devportal.couldNotLoadApplication\",\n \"Could not load application\",\n )}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n >\n <Alert\n variant=\"error\"\n title={tr(\n \"devportal.failedToLoadApplication\",\n \"Failed to load application\",\n )}\n >\n {queryError?.message ??\n tr(\"devportal.applicationNotFound\", \"Application not found\")}\n </Alert>\n </PageLayout>\n );\n }\n\n if (submitted) {\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={tr(\"devportal.publishToStoreTitle\", \"Publish to Store\")}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n >\n <div className=\"flex flex-col items-center justify-center py-16 gap-6 text-center\">\n <div className=\"rounded-full bg-status-success-bg p-4\">\n <PartyPopper size={40} className=\"text-status-success-text\" />\n </div>\n <div className=\"space-y-2\">\n <h2 className=\"text-2xl font-bold\">\n {tr(\"devportal.submittedSuccessTitle\", \"Submitted for Review!\")}\n </h2>\n <p className=\"text-muted-foreground max-w-md\">\n {tr(\n \"devportal.submittedSuccessMsg\",\n \"Your app has been submitted to the marketplace review queue. You'll receive email notifications as the review progresses — typically 3–5 business days.\",\n )}\n </p>\n </div>\n <div className=\"rounded-lg border bg-muted/40 px-6 py-4 text-sm text-left space-y-2 max-w-md w-full\">\n <p className=\"font-medium\">What happens next:</p>\n <ul className=\"space-y-1 text-muted-foreground list-none\">\n <li className=\"flex items-start gap-2\">\n <CheckCircle\n size={14}\n className=\"mt-0.5 text-status-success-text shrink-0\"\n />{\" \"}\n Our team reviews your submission\n </li>\n <li className=\"flex items-start gap-2\">\n <CheckCircle\n size={14}\n className=\"mt-0.5 text-status-success-text shrink-0\"\n />{\" \"}\n You'll get an email on approval or if changes are needed\n </li>\n <li className=\"flex items-start gap-2\">\n <CheckCircle\n size={14}\n className=\"mt-0.5 text-status-success-text shrink-0\"\n />{\" \"}\n Once approved, your app goes live in the marketplace\n </li>\n </ul>\n </div>\n <button\n onClick={() => navigate?.(`${basePath}/apps/${appId}`)}\n className=\"inline-flex items-center gap-2 rounded-md border px-4 py-2 text-sm font-medium hover:bg-muted\"\n >\n Back to App\n </button>\n </div>\n </PageLayout>\n </PermissionGuard>\n );\n }\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={tr(\"devportal.publishToStoreTitle\", \"Publish to Store\")}\n description={`${tr(\"devportal.submitAppForReview\", \"Submit\")} \"${app.name}\" ${tr(\"devportal.forReviewAndPublication\", \"for review and publication\")}`}\n purpose={tr(\n \"devportal.publishPurpose\",\n \"Submitting sends your app to the review team, who check it against the marketplace guidelines before it goes live to users. Make sure the listing, screenshots, and permissions are final — preview the listing first, since changes after approval need another review.\",\n )}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n actions={\n <button\n onClick={() => navigate?.(`${basePath}/apps/${appId}/listing`)}\n className=\"inline-flex items-center gap-2 rounded-md border px-3 py-2 text-sm font-medium hover:bg-bg-sunken\"\n >\n <Eye size={16} />\n {tr(\"devportal.previewListing\", \"Preview Listing\")}\n </button>\n }\n >\n {isAlreadySubmitted && (\n <Alert\n variant=\"warning\"\n title={tr(\"devportal.alreadySubmittedTitle\", \"Already Submitted\")}\n >\n {tr(\"devportal.alreadySubmittedMsg1\", \"This app is currently in\")}{\" \"}\n <strong>{app.status}</strong>{\" \"}\n {tr(\n \"devportal.alreadySubmittedMsg2\",\n \"state and cannot be re-submitted until the review process is complete or the app is rejected.\",\n )}\n </Alert>\n )}\n\n {/* Progress Summary */}\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-6\">\n <h2 className=\"text-lg font-semibold\">\n {tr(\"devportal.preSubmissionChecklist\", \"Pre-submission Checklist\")}\n </h2>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {tr(\n \"devportal.completeAllRequiredItems\",\n \"Complete all required items before submitting for review\",\n )}\n </p>\n <div className=\"mt-4 flex gap-6\">\n <div className=\"flex items-center gap-2\">\n <CheckCircle size={20} className=\"text-status-success-text\" />\n <span>\n {passedCount} {tr(\"devportal.passed\", \"Passed\")}\n </span>\n </div>\n <div className=\"flex items-center gap-2\">\n <XCircle size={20} className=\"text-status-error-text\" />\n <span>\n {failedCount} {tr(\"devportal.failed\", \"Failed\")}\n </span>\n </div>\n <div className=\"flex items-center gap-2\">\n <AlertTriangle size={20} className=\"text-status-warning-text\" />\n <span>\n {warningCount} {tr(\"devportal.warnings\", \"Warnings\")}\n </span>\n </div>\n </div>\n </div>\n\n {/* Checklist Items */}\n <PageSection>\n <div className=\"space-y-3\">\n {checklist.map((item) => (\n <div\n key={item.id}\n className={`flex items-center gap-4 rounded-lg border p-4 ${getStatusBg(item.status)}`}\n >\n <div className=\"rounded-lg bg-bg-surface p-2\">{item.icon}</div>\n <div className=\"flex-1\">\n <p className=\"font-medium\">{item.label}</p>\n <p className=\"text-sm text-text-secondary\">\n {item.description}\n </p>\n {item.status !== \"passed\" && item.actionPath && (\n <button\n type=\"button\"\n onClick={() =>\n navigate?.(`${basePath}${item.actionPath}`)\n }\n className=\"mt-1 inline-flex items-center gap-1 text-xs text-primary hover:underline\"\n >\n {item.actionLabel ?? \"Fix this\"} <ArrowRight size={11} />\n </button>\n )}\n </div>\n {getStatusIcon(item.status)}\n </div>\n ))}\n </div>\n </PageSection>\n\n {/* Submission Notes */}\n {!isAlreadySubmitted && (\n <PageSection\n title={tr(\"devportal.notesForReviewerTitle\", \"Notes for Reviewer\")}\n description={tr(\n \"devportal.notesForReviewerDesc\",\n \"Optional message to the review team\",\n )}\n >\n <textarea\n value={notes}\n onChange={(e) => setNotes(e.target.value)}\n placeholder={tr(\n \"devportal.notesForReviewerPlaceholder\",\n \"Describe what your app does, any special review considerations, or testing instructions...\",\n )}\n rows={4}\n maxLength={1000}\n className=\"w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm ring-offset-background placeholder:text-text-secondary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] resize-none\"\n />\n <p className=\"mt-1 text-xs text-text-secondary text-right\">\n {notes.length}/1000\n </p>\n </PageSection>\n )}\n\n {/* Alerts */}\n {submitError && (\n <Alert\n variant=\"error\"\n title={tr(\"devportal.submissionFailedTitle\", \"Submission Failed\")}\n >\n {submitError}\n </Alert>\n )}\n\n {failedCount > 0 && !isAlreadySubmitted && (\n <Alert\n variant=\"error\"\n title={tr(\"devportal.cannotSubmitTitle\", \"Cannot Submit Yet\")}\n >\n {tr(\"devportal.pleaseFixItems1\", \"Please fix\")} {failedCount}{\" \"}\n {tr(\n \"devportal.pleaseFixItems2\",\n \"required item(s) before submitting for review.\",\n )}\n <div className=\"mt-2 flex flex-wrap gap-3\">\n <button\n onClick={() => navigate?.(`${basePath}/apps/${appId}`)}\n className=\"text-sm underline hover:no-underline\"\n >\n {tr(\n \"devportal.goToMarketplaceListing\",\n \"Update marketplace listing →\",\n )}\n </button>\n {isPackageType && publishedVersionCount === 0 && (\n <button\n onClick={() =>\n navigate?.(`${basePath}/apps/${appId}/versions`)\n }\n className=\"text-sm underline hover:no-underline\"\n >\n {tr(\"devportal.goToVersions\", \"Add a published version →\")}\n </button>\n )}\n {isApiIntegration && !hasOAuthUrl && (\n <button\n onClick={() =>\n navigate?.(`${basePath}/apps/${appId}/edit#oauth-config`)\n }\n className=\"text-sm underline hover:no-underline\"\n >\n Configure OAuth endpoints →\n </button>\n )}\n {isApiIntegration && webhookCount === 0 && (\n <button\n onClick={() =>\n navigate?.(`${basePath}/apps/${appId}/webhooks`)\n }\n className=\"text-sm underline hover:no-underline\"\n >\n Add a webhook →\n </button>\n )}\n </div>\n </Alert>\n )}\n\n {warningCount > 0 && failedCount === 0 && !isAlreadySubmitted && (\n <Alert\n variant=\"warning\"\n title={tr(\"devportal.warningsTitle\", \"Warnings\")}\n >\n {tr(\"devportal.warningsMsg1\", \"You have\")} {warningCount}{\" \"}\n {tr(\n \"devportal.warningsMsg2\",\n \"warning(s). While you can submit, addressing these may improve your app's chances of approval.\",\n )}\n </Alert>\n )}\n\n {/* Review Process Info */}\n <PageSection\n title={tr(\"devportal.reviewProcessTitle\", \"Review Process\")}\n >\n <div className=\"rounded-lg border bg-bg-sunken/50 p-4\">\n <ul className=\"space-y-2 text-sm\">\n <li className=\"flex items-start gap-2\">\n <CheckCircle size={16} className=\"mt-0.5 text-primary\" />\n <span>\n {tr(\n \"devportal.reviewProcessInfo1\",\n \"Review typically takes 3-5 business days\",\n )}\n </span>\n </li>\n <li className=\"flex items-start gap-2\">\n <CheckCircle size={16} className=\"mt-0.5 text-primary\" />\n <span>\n {tr(\n \"devportal.reviewProcessInfo2\",\n \"You'll receive notifications about review status changes\",\n )}\n </span>\n </li>\n <li className=\"flex items-start gap-2\">\n <CheckCircle size={16} className=\"mt-0.5 text-primary\" />\n <span>\n {tr(\n \"devportal.reviewProcessInfo3\",\n \"If changes are requested, you can resubmit without losing your place in the queue\",\n )}\n </span>\n </li>\n <li className=\"flex items-start gap-2\">\n <CheckCircle size={16} className=\"mt-0.5 text-primary\" />\n <span>\n {tr(\n \"devportal.reviewProcessInfo4\",\n \"Once approved and published, your app will be visible in the marketplace\",\n )}\n </span>\n </li>\n </ul>\n </div>\n </PageSection>\n\n {/* Actions */}\n <div className=\"flex gap-3\">\n <button\n onClick={() => navigate?.(`${basePath}/apps/${appId}`)}\n className=\"rounded-md border px-4 py-2 text-sm font-medium hover:bg-bg-sunken\"\n >\n {tr(\"devportal.cancelButton\", \"Cancel\")}\n </button>\n <button\n onClick={handleSubmit}\n disabled={!canSubmit || submitting || !submitPerm.allowed}\n aria-disabled={!canSubmit || submitting || !submitPerm.allowed}\n title={\n !submitPerm.allowed\n ? tr(\n \"devportal.common.noPermission\",\n \"You do not have permission to perform this action\",\n )\n : undefined\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 disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary\"\n >\n {submitting ? (\n <>\n <Loader2 size={16} className=\"animate-spin\" />\n {tr(\"devportal.submittingButton\", \"Submitting...\")}\n </>\n ) : (\n <>\n <Send size={16} />\n {tr(\"devportal.submitForReviewButton\", \"Submit for Review\")}\n </>\n )}\n </button>\n </div>\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"PublishPage.js","names":[],"sources":["../../../src/devportal/pages/PublishPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useEffect, useState, useMemo } from \"react\";\nimport { useParams } from \"react-router\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n CheckCircle,\n XCircle,\n AlertTriangle,\n Send,\n FileText,\n Shield,\n Image,\n Globe,\n Loader2,\n Eye,\n ArrowRight,\n PartyPopper,\n Link,\n Webhook,\n KeyRound,\n} from \"lucide-react\";\nimport { gql } from \"@apollo/client\";\nimport { useQuery } from \"@apollo/client/react\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { Alert } from \"../components/ConfirmDialog\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport { DEVPORTAL_PERMISSIONS } from \"../constants/permissions\";\nimport {\n useGetApplicationQuery,\n useSubmitApplicationMutation,\n useSubmitApplicationForReviewMutation,\n} from \"../../generated/global-operations\";\nimport { useDevportalPermission } from \"../hooks\";\n\nconst MY_PUBLISHER_QUERY = gql`\n query PublishPagePublisher {\n myPublisher {\n id\n }\n }\n`;\nconst PUBLISHER_PRODUCTS_QUERY = gql`\n query PublishPageProducts($publisherId: String!) {\n products(filter: { publisherId: $publisherId }) {\n id\n productId\n }\n }\n`;\nconst APP_WEBHOOKS_QUERY = gql`\n query PublishPageWebhooks($applicationId: ID!) {\n webhooks(applicationId: $applicationId) {\n id\n }\n }\n`;\n\ninterface ChecklistItem {\n id: string;\n label: string;\n description: string;\n status: \"passed\" | \"failed\" | \"warning\" | \"pending\";\n icon: React.ReactNode;\n actionLabel?: string;\n actionPath?: string;\n}\n\nconst ALREADY_SUBMITTED_STATUSES = [\n \"SUBMITTED\",\n \"IN_REVIEW\",\n \"APPROVED\",\n \"PUBLISHED\",\n];\n\nexport const PublishPage: FC = () => {\n const { appId } = useParams<{ appId: string }>();\n const { navigate, basePath } = useDevportal();\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 [submitting, setSubmitting] = useState(false);\n const [submitError, setSubmitError] = useState<string | null>(null);\n const [submitted, setSubmitted] = useState(false);\n const [notes, setNotes] = useState(\"\");\n const submitPerm = useDevportalPermission(DEVPORTAL_PERMISSIONS.APP_SUBMIT);\n\n const {\n data,\n loading,\n error: queryError,\n } = useGetApplicationQuery({\n variables: { id: appId! },\n skip: !appId,\n fetchPolicy: \"network-only\",\n });\n\n const [submitApplication] = useSubmitApplicationMutation();\n const [submitApplicationForReview] = useSubmitApplicationForReviewMutation();\n\n // Two-step publisher lookup to find linked StoreProduct\n const { data: publisherData } = useQuery<{\n myPublisher: { id: string } | null;\n }>(MY_PUBLISHER_QUERY, { fetchPolicy: \"cache-first\" });\n const publisherId = publisherData?.myPublisher?.id ?? null;\n const { data: productsData } = useQuery<{\n products: { id: string; productId?: string | null }[];\n }>(PUBLISHER_PRODUCTS_QUERY, {\n variables: { publisherId: publisherId ?? \"\" },\n skip: !publisherId,\n fetchPolicy: \"cache-first\",\n });\n const linkedStoreProductId =\n productsData?.products?.find(\n (p: { id: string; productId?: string | null }) => p.productId === appId,\n )?.id ?? null;\n\n const isApiIntegration = data?.application?.appType === \"API_INTEGRATION\";\n const appManifest = data?.application?.manifest as\n | Record<string, unknown>\n | null\n | undefined;\n const appOauth = appManifest?.[\"oauth\"] as\n | Record<string, unknown>\n | undefined;\n const hasOAuthUrl = !!(\n appOauth?.[\"authorizationUrl\"] &&\n appOauth?.[\"tokenUrl\"] &&\n appOauth?.[\"clientId\"]\n );\n\n const { data: webhooksData } = useQuery<{ webhooks: { id: string }[] }>(\n APP_WEBHOOKS_QUERY,\n {\n variables: { applicationId: appId! },\n skip: !appId || !isApiIntegration,\n fetchPolicy: \"network-only\",\n },\n );\n const webhookCount = webhooksData?.webhooks?.length ?? 0;\n\n const app = data?.application;\n\n useEffect(() => {\n const name = app?.name;\n if (!appId || !name) return;\n const reg = (\n window as unknown as {\n __breadcrumbRegistry?: {\n register: (id: string, name: string) => void;\n unregister: (id: string) => void;\n };\n }\n ).__breadcrumbRegistry;\n reg?.register(appId, name);\n return () => reg?.unregister(appId);\n }, [appId, app?.name]);\n\n const isAlreadySubmitted = ALREADY_SUBMITTED_STATUSES.includes(\n app?.status ?? \"\",\n );\n\n const isPackageType = app?.appType === \"NODE\" || app?.appType === \"WORKFLOW\";\n const publishedVersionCount = app?.versions?.totalCount ?? 0;\n\n const checklist = useMemo((): ChecklistItem[] => {\n if (!app) return [];\n\n const screenshotCount = app.screenshots?.length ?? 0;\n\n const storeListingPath = `/apps/${appId}?tab=store-listing`;\n const versionsPath = `/apps/${appId}/versions`;\n const editPath = `/apps/${appId}/edit#oauth-config`;\n const webhooksPath = `/apps/${appId}/webhooks`;\n\n const items: ChecklistItem[] = [\n {\n id: \"name\",\n label: tr(\"devportal.checklistNameLabel\", \"Name & Short Description\"),\n description: tr(\n \"devportal.checklistNameDesc\",\n \"Name and short description are required for the store card\",\n ),\n status: app.name && app.shortDescription ? \"passed\" : \"failed\",\n icon: <FileText size={20} />,\n actionLabel: \"Edit store listing →\",\n actionPath: storeListingPath,\n },\n {\n id: \"category\",\n label: tr(\"devportal.checklistCategoryLabel\", \"Category\"),\n description: tr(\n \"devportal.checklistCategoryDesc\",\n \"A category helps users find your item in the marketplace\",\n ),\n status: app.category ? \"passed\" : \"failed\",\n icon: <Globe size={20} />,\n actionLabel: \"Edit app info →\",\n actionPath: `/apps/${appId}/edit`,\n },\n {\n id: \"privacy\",\n label: tr(\"devportal.checklistPrivacyLabel\", \"Privacy Policy\"),\n description: tr(\n \"devportal.checklistPrivacyDesc\",\n \"Privacy policy URL is required for store submission\",\n ),\n status: app.privacyPolicyUrl ? \"passed\" : \"failed\",\n icon: <Shield size={20} />,\n actionLabel: \"Edit store listing →\",\n actionPath: storeListingPath,\n },\n {\n id: \"terms\",\n label: tr(\"devportal.checklistTermsLabel\", \"Terms of Service\"),\n description: tr(\n \"devportal.checklistTermsDesc\",\n \"Terms of service URL is required for store submission\",\n ),\n status: app.termsOfServiceUrl ? \"passed\" : \"failed\",\n icon: <FileText size={20} />,\n actionLabel: \"Edit store listing →\",\n actionPath: storeListingPath,\n },\n {\n id: \"icon\",\n label: tr(\"devportal.checklistIconLabel\", \"App Icon\"),\n description: tr(\n \"devportal.checklistIconDesc\",\n \"An icon makes your listing stand out in the marketplace\",\n ),\n status: app.iconUrl ? \"passed\" : \"warning\",\n icon: <Image size={20} />,\n actionLabel: \"Edit store listing →\",\n actionPath: storeListingPath,\n },\n {\n id: \"screenshots\",\n label: tr(\"devportal.checklistScreenshotsLabel\", \"Screenshots\"),\n description: tr(\n \"devportal.checklistScreenshotsDesc\",\n \"At least 3 screenshots are recommended\",\n ),\n status:\n screenshotCount >= 3\n ? \"passed\"\n : screenshotCount > 0\n ? \"warning\"\n : \"warning\",\n icon: <Image size={20} />,\n actionLabel: \"Edit store listing →\",\n actionPath: storeListingPath,\n },\n ];\n\n if (isPackageType) {\n items.push({\n id: \"version\",\n label: tr(\"devportal.checklistVersionLabel\", \"Published Version\"),\n description: tr(\n \"devportal.checklistVersionDesc\",\n app?.appType === \"WORKFLOW\"\n ? \"At least one published version (manifest JSON) is required before submitting to the store\"\n : \"At least one published version (ZIP + manifest) is required before submitting to the store\",\n ),\n status: publishedVersionCount > 0 ? \"passed\" : \"failed\",\n icon: <CheckCircle size={20} />,\n actionLabel: \"Create a version →\",\n actionPath: versionsPath,\n });\n }\n\n if (app.appType === \"API_INTEGRATION\") {\n items.push({\n id: \"oauth\",\n label: tr(\"devportal.checklistOAuthLabel\", \"OAuth Configuration\"),\n description: tr(\n \"devportal.checklistOAuthDesc\",\n \"Authorization URL, Token URL and Client ID are required so users can connect their accounts. Without these the Connect button does not work.\",\n ),\n status: hasOAuthUrl ? \"passed\" : \"failed\",\n icon: <KeyRound size={20} />,\n actionLabel: \"Configure in Edit App →\",\n actionPath: editPath,\n });\n\n items.push({\n id: \"webhook\",\n label: tr(\"devportal.checklistWebhookLabel\", \"Webhook Endpoint\"),\n description: tr(\n \"devportal.checklistWebhookDesc\",\n \"At least one webhook endpoint must be configured so your server receives platform events after users connect. Without this the integration does nothing.\",\n ),\n status: webhookCount > 0 ? \"passed\" : \"failed\",\n icon: <Webhook size={20} />,\n actionLabel: \"Add a webhook →\",\n actionPath: webhooksPath,\n });\n\n items.push({\n id: \"documentation\",\n label: tr(\"devportal.checklistDocsLabel\", \"Documentation URL\"),\n description: tr(\n \"devportal.checklistDocsDesc\",\n \"Users need to know how to use and configure this integration. A documentation link is required for API integrations.\",\n ),\n status: app.documentationUrl ? \"passed\" : \"failed\",\n icon: <FileText size={20} />,\n actionLabel: \"Add documentation URL →\",\n actionPath: editPath,\n });\n\n items.push({\n id: \"website\",\n label: tr(\"devportal.checklistWebsiteLabel\", \"Website URL\"),\n description: tr(\n \"devportal.checklistWebsiteDesc\",\n \"Users need to verify who built this integration. A website URL is required so users know where to get support.\",\n ),\n status: app.websiteUrl ? \"passed\" : \"failed\",\n icon: <Link size={20} />,\n actionLabel: \"Add website URL →\",\n actionPath: editPath,\n });\n }\n\n items.push({\n id: \"status\",\n label: tr(\"devportal.checklistStatusLabel\", \"App Status\"),\n description: tr(\n \"devportal.checklistStatusDesc\",\n \"App must be in DRAFT or REJECTED state to submit\",\n ),\n status: [\"DRAFT\", \"REJECTED\"].includes(app.status ?? \"\")\n ? \"passed\"\n : \"warning\",\n icon: <CheckCircle size={20} />,\n });\n\n return items;\n }, [\n app,\n isPackageType,\n publishedVersionCount,\n webhookCount,\n hasOAuthUrl,\n appId,\n ]);\n\n const passedCount = checklist.filter((i) => i.status === \"passed\").length;\n const failedCount = checklist.filter((i) => i.status === \"failed\").length;\n const warningCount = checklist.filter((i) => i.status === \"warning\").length;\n const isSubmittableStatus = [\"DRAFT\", \"REJECTED\"].includes(app?.status ?? \"\");\n const canSubmit =\n !loading &&\n !queryError &&\n failedCount === 0 &&\n !!app &&\n !isAlreadySubmitted &&\n isSubmittableStatus;\n\n const getStatusIcon = (status: ChecklistItem[\"status\"]) => {\n switch (status) {\n case \"passed\":\n return <CheckCircle size={20} className=\"text-status-success-text\" />;\n case \"failed\":\n return <XCircle size={20} className=\"text-status-error-text\" />;\n case \"warning\":\n return <AlertTriangle size={20} className=\"text-status-warning-text\" />;\n default:\n return (\n <div className=\"h-5 w-5 rounded-full border-2 border-border-default\" />\n );\n }\n };\n\n const getStatusBg = (status: ChecklistItem[\"status\"]) => {\n switch (status) {\n case \"passed\":\n return \"bg-status-success-bg-subtle border-border-subtle\";\n case \"failed\":\n return \"bg-status-error-bg-subtle border-border-subtle\";\n case \"warning\":\n return \"bg-status-warning-bg-subtle border-border-subtle\";\n default:\n return \"bg-bg-canvas border-border-subtle\";\n }\n };\n\n const handleSubmit = async () => {\n if (!appId) return;\n setSubmitting(true);\n setSubmitError(null);\n try {\n // Submit Application for devportal review (sets Application.status = SUBMITTED)\n const result = await submitApplication({\n variables: { id: appId, notes: notes.trim() || undefined },\n });\n if (result.error) throw result.error;\n\n // Also submit ApplicationForReview to set StoreProduct.status = PENDING_REVIEW\n // so it appears in the store admin review queue at /store/dashboard/submissions\n await submitApplicationForReview({\n variables: { id: appId, notes: notes.trim() || undefined },\n });\n\n setSubmitted(true);\n } catch (err) {\n setSubmitError(\n err instanceof Error\n ? err.message\n : tr(\"devportal.submitFailedDefault\", \"Failed to submit for review\"),\n );\n } finally {\n setSubmitting(false);\n }\n };\n\n if (loading) {\n return (\n <PageLayout\n title={tr(\"devportal.publishToStoreTitle\", \"Publish to Store\")}\n description={tr(\n \"devportal.loadingApplicationDetails\",\n \"Loading application details...\",\n )}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n >\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"animate-spin h-8 w-8 text-text-secondary\" />\n </div>\n </PageLayout>\n );\n }\n\n if (queryError || !app) {\n return (\n <PageLayout\n title={tr(\"devportal.publishToStoreTitle\", \"Publish to Store\")}\n description={tr(\n \"devportal.couldNotLoadApplication\",\n \"Could not load application\",\n )}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n >\n <Alert\n variant=\"error\"\n title={tr(\n \"devportal.failedToLoadApplication\",\n \"Failed to load application\",\n )}\n >\n {queryError?.message ??\n tr(\"devportal.applicationNotFound\", \"Application not found\")}\n </Alert>\n </PageLayout>\n );\n }\n\n if (submitted) {\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={tr(\"devportal.publishToStoreTitle\", \"Publish to Store\")}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n >\n <div className=\"flex flex-col items-center justify-center py-16 gap-6 text-center\">\n <div className=\"rounded-full bg-status-success-bg p-4\">\n <PartyPopper size={40} className=\"text-status-success-text\" />\n </div>\n <div className=\"space-y-2\">\n <h2 className=\"text-2xl font-bold\">\n {tr(\"devportal.submittedSuccessTitle\", \"Submitted for Review!\")}\n </h2>\n <p className=\"text-muted-foreground max-w-md\">\n {tr(\n \"devportal.submittedSuccessMsg\",\n \"Your app has been submitted to the marketplace review queue. You'll receive email notifications as the review progresses — typically 3–5 business days.\",\n )}\n </p>\n </div>\n <div className=\"rounded-lg border bg-muted/40 px-6 py-4 text-sm text-left space-y-2 max-w-md w-full\">\n <p className=\"font-medium\">What happens next:</p>\n <ul className=\"space-y-1 text-muted-foreground list-none\">\n <li className=\"flex items-start gap-2\">\n <CheckCircle\n size={14}\n className=\"mt-0.5 text-status-success-text shrink-0\"\n />{\" \"}\n Our team reviews your submission\n </li>\n <li className=\"flex items-start gap-2\">\n <CheckCircle\n size={14}\n className=\"mt-0.5 text-status-success-text shrink-0\"\n />{\" \"}\n You'll get an email on approval or if changes are needed\n </li>\n <li className=\"flex items-start gap-2\">\n <CheckCircle\n size={14}\n className=\"mt-0.5 text-status-success-text shrink-0\"\n />{\" \"}\n Once approved, your app goes live in the marketplace\n </li>\n </ul>\n </div>\n <button\n onClick={() => navigate?.(`${basePath}/apps/${appId}`)}\n className=\"inline-flex items-center gap-2 rounded-md border px-4 py-2 text-sm font-medium hover:bg-muted\"\n >\n Back to App\n </button>\n </div>\n </PageLayout>\n </PermissionGuard>\n );\n }\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={tr(\"devportal.publishToStoreTitle\", \"Publish to Store\")}\n description={`${tr(\"devportal.submitAppForReview\", \"Submit\")} \"${app.name}\" ${tr(\"devportal.forReviewAndPublication\", \"for review and publication\")}`}\n purpose={tr(\n \"devportal.publishPurpose\",\n \"Submitting sends your app to the review team, who check it against the marketplace guidelines before it goes live to users. Make sure the listing, screenshots, and permissions are final — preview the listing first, since changes after approval need another review.\",\n )}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n actions={\n <button\n onClick={() => navigate?.(`${basePath}/apps/${appId}/listing`)}\n className=\"inline-flex items-center gap-2 rounded-md border px-3 py-2 text-sm font-medium hover:bg-bg-sunken\"\n >\n <Eye size={16} />\n {tr(\"devportal.previewListing\", \"Preview Listing\")}\n </button>\n }\n >\n {isAlreadySubmitted && (\n <Alert\n variant=\"warning\"\n title={tr(\"devportal.alreadySubmittedTitle\", \"Already Submitted\")}\n >\n {tr(\"devportal.alreadySubmittedMsg1\", \"This app is currently in\")}{\" \"}\n <strong>{app.status}</strong>{\" \"}\n {tr(\n \"devportal.alreadySubmittedMsg2\",\n \"state and cannot be re-submitted until the review process is complete or the app is rejected.\",\n )}\n </Alert>\n )}\n\n {/* Progress Summary */}\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-6\">\n <h2 className=\"text-lg font-semibold\">\n {tr(\"devportal.preSubmissionChecklist\", \"Pre-submission Checklist\")}\n </h2>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {tr(\n \"devportal.completeAllRequiredItems\",\n \"Complete all required items before submitting for review\",\n )}\n </p>\n <div className=\"mt-4 flex gap-6\">\n <div className=\"flex items-center gap-2\">\n <CheckCircle size={20} className=\"text-status-success-text\" />\n <span>\n {passedCount} {tr(\"devportal.passed\", \"Passed\")}\n </span>\n </div>\n <div className=\"flex items-center gap-2\">\n <XCircle size={20} className=\"text-status-error-text\" />\n <span>\n {failedCount} {tr(\"devportal.failed\", \"Failed\")}\n </span>\n </div>\n <div className=\"flex items-center gap-2\">\n <AlertTriangle size={20} className=\"text-status-warning-text\" />\n <span>\n {warningCount} {tr(\"devportal.warnings\", \"Warnings\")}\n </span>\n </div>\n </div>\n </div>\n\n {/* Checklist Items */}\n <PageSection>\n <div className=\"space-y-3\">\n {checklist.map((item) => (\n <div\n key={item.id}\n className={`flex items-center gap-4 rounded-lg border p-4 ${getStatusBg(item.status)}`}\n >\n <div className=\"rounded-lg bg-bg-surface p-2\">{item.icon}</div>\n <div className=\"flex-1\">\n <p className=\"font-medium\">{item.label}</p>\n <p className=\"text-sm text-text-secondary\">\n {item.description}\n </p>\n {item.status !== \"passed\" && item.actionPath && (\n <button\n type=\"button\"\n onClick={() =>\n navigate?.(`${basePath}${item.actionPath}`)\n }\n className=\"mt-1 inline-flex items-center gap-1 text-xs text-primary hover:underline\"\n >\n {item.actionLabel ?? \"Fix this\"} <ArrowRight size={11} />\n </button>\n )}\n </div>\n {getStatusIcon(item.status)}\n </div>\n ))}\n </div>\n </PageSection>\n\n {/* Submission Notes */}\n {!isAlreadySubmitted && (\n <PageSection\n title={tr(\"devportal.notesForReviewerTitle\", \"Notes for Reviewer\")}\n description={tr(\n \"devportal.notesForReviewerDesc\",\n \"Optional message to the review team\",\n )}\n >\n <textarea\n value={notes}\n onChange={(e) => setNotes(e.target.value)}\n placeholder={tr(\n \"devportal.notesForReviewerPlaceholder\",\n \"Describe what your app does, any special review considerations, or testing instructions...\",\n )}\n rows={4}\n maxLength={1000}\n className=\"w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm ring-offset-background placeholder:text-text-secondary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] resize-none\"\n />\n <p className=\"mt-1 text-xs text-text-secondary text-right\">\n {notes.length}/1000\n </p>\n </PageSection>\n )}\n\n {/* Alerts */}\n {submitError && (\n <Alert\n variant=\"error\"\n title={tr(\"devportal.submissionFailedTitle\", \"Submission Failed\")}\n >\n {submitError}\n </Alert>\n )}\n\n {failedCount > 0 && !isAlreadySubmitted && (\n <Alert\n variant=\"error\"\n title={tr(\"devportal.cannotSubmitTitle\", \"Cannot Submit Yet\")}\n >\n {tr(\"devportal.pleaseFixItems1\", \"Please fix\")} {failedCount}{\" \"}\n {tr(\n \"devportal.pleaseFixItems2\",\n \"required item(s) before submitting for review.\",\n )}\n <div className=\"mt-2 flex flex-wrap gap-3\">\n <button\n onClick={() => navigate?.(`${basePath}/apps/${appId}`)}\n className=\"text-sm underline hover:no-underline\"\n >\n {tr(\n \"devportal.goToMarketplaceListing\",\n \"Update marketplace listing →\",\n )}\n </button>\n {isPackageType && publishedVersionCount === 0 && (\n <button\n onClick={() =>\n navigate?.(`${basePath}/apps/${appId}/versions`)\n }\n className=\"text-sm underline hover:no-underline\"\n >\n {tr(\"devportal.goToVersions\", \"Add a published version →\")}\n </button>\n )}\n {isApiIntegration && !hasOAuthUrl && (\n <button\n onClick={() =>\n navigate?.(`${basePath}/apps/${appId}/edit#oauth-config`)\n }\n className=\"text-sm underline hover:no-underline\"\n >\n Configure OAuth endpoints →\n </button>\n )}\n {isApiIntegration && webhookCount === 0 && (\n <button\n onClick={() =>\n navigate?.(`${basePath}/apps/${appId}/webhooks`)\n }\n className=\"text-sm underline hover:no-underline\"\n >\n Add a webhook →\n </button>\n )}\n </div>\n </Alert>\n )}\n\n {warningCount > 0 && failedCount === 0 && !isAlreadySubmitted && (\n <Alert\n variant=\"warning\"\n title={tr(\"devportal.warningsTitle\", \"Warnings\")}\n >\n {tr(\"devportal.warningsMsg1\", \"You have\")} {warningCount}{\" \"}\n {tr(\n \"devportal.warningsMsg2\",\n \"warning(s). While you can submit, addressing these may improve your app's chances of approval.\",\n )}\n </Alert>\n )}\n\n {/* Review Process Info */}\n <PageSection\n title={tr(\"devportal.reviewProcessTitle\", \"Review Process\")}\n >\n <div className=\"rounded-lg border bg-bg-sunken/50 p-4\">\n <ul className=\"space-y-2 text-sm\">\n <li className=\"flex items-start gap-2\">\n <CheckCircle size={16} className=\"mt-0.5 text-primary\" />\n <span>\n {tr(\n \"devportal.reviewProcessInfo1\",\n \"Review typically takes 3-5 business days\",\n )}\n </span>\n </li>\n <li className=\"flex items-start gap-2\">\n <CheckCircle size={16} className=\"mt-0.5 text-primary\" />\n <span>\n {tr(\n \"devportal.reviewProcessInfo2\",\n \"You'll receive notifications about review status changes\",\n )}\n </span>\n </li>\n <li className=\"flex items-start gap-2\">\n <CheckCircle size={16} className=\"mt-0.5 text-primary\" />\n <span>\n {tr(\n \"devportal.reviewProcessInfo3\",\n \"If changes are requested, you can resubmit without losing your place in the queue\",\n )}\n </span>\n </li>\n <li className=\"flex items-start gap-2\">\n <CheckCircle size={16} className=\"mt-0.5 text-primary\" />\n <span>\n {tr(\n \"devportal.reviewProcessInfo4\",\n \"Once approved and published, your app will be visible in the marketplace\",\n )}\n </span>\n </li>\n </ul>\n </div>\n </PageSection>\n\n {/* Actions */}\n <div className=\"flex gap-3\">\n <button\n onClick={() => navigate?.(`${basePath}/apps/${appId}`)}\n className=\"rounded-md border px-4 py-2 text-sm font-medium hover:bg-bg-sunken\"\n >\n {tr(\"devportal.cancelButton\", \"Cancel\")}\n </button>\n <button\n onClick={handleSubmit}\n disabled={!canSubmit || submitting || !submitPerm.allowed}\n aria-disabled={!canSubmit || submitting || !submitPerm.allowed}\n title={\n !submitPerm.allowed\n ? tr(\n \"devportal.common.noPermission\",\n \"You do not have permission to perform this action\",\n )\n : undefined\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 disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary\"\n >\n {submitting ? (\n <>\n <Loader2 size={16} className=\"animate-spin\" />\n {tr(\"devportal.submittingButton\", \"Submitting...\")}\n </>\n ) : (\n <>\n <Send size={16} />\n {tr(\"devportal.submitForReviewButton\", \"Submit for Review\")}\n </>\n )}\n </button>\n </div>\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
@@ -9,12 +9,12 @@ import "../components/index.js";
9
9
  import { useDevportalPermission as c } from "../hooks/usePermission.js";
10
10
  import { DEVPORTAL_PERMISSIONS as l } from "../constants/permissions.js";
11
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";
12
+ import { AlertCircle as f, CheckCircle2 as p, Info as m, Loader2 as h, Save as g, Store as _ } from "lucide-react";
13
+ import { jsx as v, jsxs as y } from "react/jsx-runtime";
14
+ import { useI18n as b } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
15
15
  //#region src/devportal/pages/PublisherProfilePage.tsx
16
16
  var x = () => {
17
- let { t: x } = f(), S = (e, t) => {
17
+ let { t: x } = b(), S = (e, t) => {
18
18
  let n = x(e);
19
19
  return n === e ? t : n;
20
20
  }, { currentUser: C } = e(), { allowed: w } = c(l.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");
@@ -28,38 +28,38 @@ var x = () => {
28
28
  j,
29
29
  E,
30
30
  C
31
- ]), E && !j ? /* @__PURE__ */ y(i, {
31
+ ]), E && !j ? /* @__PURE__ */ v(i, {
32
32
  title: S("devportal.publisherProfileTitle", "Publisher Profile"),
33
33
  description: S("devportal.loadingPublisherProfile", "Loading your publisher profile..."),
34
- children: /* @__PURE__ */ y("div", {
34
+ children: /* @__PURE__ */ v("div", {
35
35
  className: "flex items-center justify-center py-20",
36
- children: /* @__PURE__ */ y(g, { className: "h-8 w-8 animate-spin text-text-secondary" })
36
+ children: /* @__PURE__ */ v(h, { className: "h-8 w-8 animate-spin text-text-secondary" })
37
37
  })
38
- }) : D && !j ? /* @__PURE__ */ y(i, {
38
+ }) : D && !j ? /* @__PURE__ */ v(i, {
39
39
  title: S("devportal.publisherProfileTitle", "Publisher Profile"),
40
40
  description: S("devportal.manageStorePublisherPresence", "Manage your store publisher presence"),
41
- children: /* @__PURE__ */ b("div", {
41
+ children: /* @__PURE__ */ y("div", {
42
42
  className: "flex flex-col items-center justify-center gap-4 py-20",
43
43
  children: [
44
- /* @__PURE__ */ y(p, { className: "h-12 w-12 text-status-error-text" }),
45
- /* @__PURE__ */ y("p", {
44
+ /* @__PURE__ */ v(f, { className: "h-12 w-12 text-status-error-text" }),
45
+ /* @__PURE__ */ v("p", {
46
46
  className: "text-text-secondary",
47
47
  children: S("devportal.failedToLoadProfile", "Failed to load profile")
48
48
  }),
49
- /* @__PURE__ */ y("button", {
49
+ /* @__PURE__ */ v("button", {
50
50
  onClick: () => O(),
51
51
  className: "rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
52
52
  children: S("devportal.retryButton", "Retry")
53
53
  })
54
54
  ]
55
55
  })
56
- }) : /* @__PURE__ */ y(s, {
56
+ }) : /* @__PURE__ */ v(s, {
57
57
  authOnly: !0,
58
- children: /* @__PURE__ */ b(i, {
58
+ children: /* @__PURE__ */ y(i, {
59
59
  title: S("devportal.publisherProfileTitle", "Publisher Profile"),
60
60
  description: S("devportal.manageMarketplaceAppearance", "Manage how you appear to users in the marketplace"),
61
61
  purpose: S("devportal.publisherProfilePurpose", "This is your public face in the marketplace — the name, logo, bio, and links users see before installing your apps. A complete, trustworthy profile makes shoppers more likely to install and is required before some apps can be published."),
62
- actions: /* @__PURE__ */ b("button", {
62
+ actions: /* @__PURE__ */ y("button", {
63
63
  onClick: async () => {
64
64
  let e = j?.userId ?? C?.id;
65
65
  if (e) {
@@ -88,50 +88,50 @@ var x = () => {
88
88
  disabled: A || !w,
89
89
  "aria-disabled": !w,
90
90
  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-status-error-bg text-status-error-text" : "bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg/90", A && "opacity-50 cursor-not-allowed"),
91
- children: [A ? /* @__PURE__ */ y(g, {
91
+ children: [A ? /* @__PURE__ */ v(h, {
92
92
  size: 16,
93
93
  className: "animate-spin"
94
- }) : 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")]
94
+ }) : v(W === "saved" ? p : W === "error" ? f : g, { size: 16 }), A ? S("devportal.savingButton", "Saving...") : W === "saved" ? S("devportal.savedButton", "Saved!") : W === "error" ? S("devportal.errorButton", "Error") : S("devportal.saveChangesButton", "Save Changes")]
95
95
  }),
96
- children: [/* @__PURE__ */ b("div", {
96
+ children: [/* @__PURE__ */ y("div", {
97
97
  className: "flex gap-3 rounded-lg border border-border-subtle bg-status-info-bg-subtle p-4 text-sm text-status-info-text",
98
- children: [/* @__PURE__ */ y(h, {
98
+ children: [/* @__PURE__ */ v(m, {
99
99
  size: 16,
100
100
  className: "flex-shrink-0 mt-0.5"
101
- }), /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
101
+ }), /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
102
102
  className: "font-medium",
103
103
  children: S("devportal.publisherProfilesWorkTitle", "How publisher profiles work")
104
- }), /* @__PURE__ */ y("p", {
104
+ }), /* @__PURE__ */ v("p", {
105
105
  className: "mt-1 text-status-info-text",
106
106
  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.")
107
107
  })] })]
108
- }), /* @__PURE__ */ b("div", {
108
+ }), /* @__PURE__ */ y("div", {
109
109
  className: "grid grid-cols-1 gap-6 lg:grid-cols-3",
110
- children: [/* @__PURE__ */ b("div", {
110
+ children: [/* @__PURE__ */ y("div", {
111
111
  className: "lg:col-span-2 space-y-6",
112
- children: [/* @__PURE__ */ y(a, {
112
+ children: [/* @__PURE__ */ v(a, {
113
113
  title: S("devportal.publisherIdentityTitle", "Publisher Identity"),
114
114
  description: S("devportal.publisherIdentityDesc", "Displayed on your marketplace listings"),
115
- children: /* @__PURE__ */ b("div", {
115
+ children: /* @__PURE__ */ y("div", {
116
116
  className: "space-y-4",
117
117
  children: [
118
- /* @__PURE__ */ y(o, {
118
+ /* @__PURE__ */ v(o, {
119
119
  label: S("devportal.displayNameLabel", "Display Name / Company"),
120
120
  value: M,
121
121
  onChange: (e) => N(e.target.value),
122
122
  placeholder: S("devportal.displayNamePlaceholder", "Your name or company (shown on all your apps)")
123
123
  }),
124
- /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("label", {
124
+ /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
125
125
  className: "text-sm font-medium text-text-primary",
126
126
  children: S("devportal.bioLabel", "Bio")
127
- }), /* @__PURE__ */ y("textarea", {
127
+ }), /* @__PURE__ */ v("textarea", {
128
128
  value: I,
129
129
  onChange: (e) => L(e.target.value),
130
130
  placeholder: S("devportal.bioPlaceholder", "A short description of you or your company shown on the marketplace..."),
131
131
  rows: 3,
132
132
  className: "mt-1 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm ring-offset-background placeholder:text-text-secondary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] resize-none"
133
133
  })] }),
134
- /* @__PURE__ */ y(o, {
134
+ /* @__PURE__ */ v(o, {
135
135
  label: S("devportal.websiteLabel", "Website"),
136
136
  value: P,
137
137
  onChange: (e) => F(e.target.value),
@@ -139,25 +139,25 @@ var x = () => {
139
139
  })
140
140
  ]
141
141
  })
142
- }), /* @__PURE__ */ y(a, {
142
+ }), /* @__PURE__ */ v(a, {
143
143
  title: S("devportal.socialLinksTitle", "Social Links"),
144
144
  description: S("devportal.socialLinksDesc", "Build trust with your developer community"),
145
- children: /* @__PURE__ */ b("div", {
145
+ children: /* @__PURE__ */ y("div", {
146
146
  className: "space-y-4",
147
147
  children: [
148
- /* @__PURE__ */ y(o, {
148
+ /* @__PURE__ */ v(o, {
149
149
  label: S("devportal.githubUsernameLabel", "GitHub Username"),
150
150
  value: R,
151
151
  onChange: (e) => z(e.target.value),
152
152
  placeholder: S("devportal.githubUsernamePlaceholder", "your-github-username")
153
153
  }),
154
- /* @__PURE__ */ y(o, {
154
+ /* @__PURE__ */ v(o, {
155
155
  label: S("devportal.twitterUsernameLabel", "Twitter / X Username"),
156
156
  value: B,
157
157
  onChange: (e) => V(e.target.value),
158
158
  placeholder: S("devportal.twitterUsernamePlaceholder", "your_twitter")
159
159
  }),
160
- /* @__PURE__ */ y(o, {
160
+ /* @__PURE__ */ v(o, {
161
161
  label: S("devportal.linkedinUrlLabel", "LinkedIn URL"),
162
162
  value: H,
163
163
  onChange: (e) => U(e.target.value),
@@ -166,25 +166,25 @@ var x = () => {
166
166
  ]
167
167
  })
168
168
  })]
169
- }), /* @__PURE__ */ b("div", {
169
+ }), /* @__PURE__ */ y("div", {
170
170
  className: "space-y-6",
171
171
  children: [
172
- /* @__PURE__ */ y(a, {
172
+ /* @__PURE__ */ v(a, {
173
173
  title: S("devportal.publisherStatusTitle", "Publisher Status"),
174
- children: /* @__PURE__ */ b("div", {
174
+ children: /* @__PURE__ */ y("div", {
175
175
  className: "flex items-center gap-3",
176
- children: [/* @__PURE__ */ y(v, { className: "h-8 w-8 text-primary" }), /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
176
+ children: [/* @__PURE__ */ v(_, { className: "h-8 w-8 text-primary" }), /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
177
177
  className: "font-medium",
178
178
  children: j?.isVerified ? S("devportal.verifiedPublisher", "Verified Publisher") : S("devportal.publisher", "Publisher")
179
- }), /* @__PURE__ */ y("p", {
179
+ }), /* @__PURE__ */ v("p", {
180
180
  className: "text-xs text-text-secondary",
181
181
  children: j?.isVerified ? S("devportal.publisherIdentityVerified", "Your publisher identity is verified") : S("devportal.publishFirstAppMessage", "Publish your first app to appear in the marketplace")
182
182
  })] })]
183
183
  })
184
184
  }),
185
- /* @__PURE__ */ y(a, {
185
+ /* @__PURE__ */ v(a, {
186
186
  title: S("devportal.profileCompletenessTitle", "Profile Completeness"),
187
- children: /* @__PURE__ */ y("div", {
187
+ children: /* @__PURE__ */ v("div", {
188
188
  className: "space-y-2",
189
189
  children: [
190
190
  {
@@ -207,49 +207,49 @@ var x = () => {
207
207
  label: S("devportal.completenessSocialLinks", "Social links"),
208
208
  ok: !!B || !!H
209
209
  }
210
- ].map(({ label: e, ok: t }) => /* @__PURE__ */ b("div", {
210
+ ].map(({ label: e, ok: t }) => /* @__PURE__ */ y("div", {
211
211
  className: "flex items-center gap-2 text-sm",
212
- children: [t ? /* @__PURE__ */ y(m, {
212
+ children: [t ? /* @__PURE__ */ v(p, {
213
213
  size: 14,
214
214
  className: "text-status-success-text"
215
- }) : /* @__PURE__ */ y("div", { className: "h-3.5 w-3.5 rounded-full border-2 border-muted-foreground" }), /* @__PURE__ */ y("span", {
215
+ }) : /* @__PURE__ */ v("div", { className: "h-3.5 w-3.5 rounded-full border-2 border-muted-foreground" }), /* @__PURE__ */ v("span", {
216
216
  className: t ? "text-text-primary" : "text-text-secondary",
217
217
  children: e
218
218
  })]
219
219
  }, e))
220
220
  })
221
221
  }),
222
- /* @__PURE__ */ y(a, {
222
+ /* @__PURE__ */ v(a, {
223
223
  title: S("devportal.marketplaceStatsTitle", "Marketplace Stats"),
224
- children: /* @__PURE__ */ b("div", {
224
+ children: /* @__PURE__ */ y("div", {
225
225
  className: "space-y-3 text-sm",
226
226
  children: [
227
- /* @__PURE__ */ b("div", {
227
+ /* @__PURE__ */ y("div", {
228
228
  className: "flex justify-between",
229
- children: [/* @__PURE__ */ y("span", {
229
+ children: [/* @__PURE__ */ v("span", {
230
230
  className: "text-text-secondary",
231
231
  children: S("devportal.publishedAppsLabel", "Published apps")
232
- }), /* @__PURE__ */ y("span", {
232
+ }), /* @__PURE__ */ v("span", {
233
233
  className: "font-semibold",
234
234
  children: j?.applicationCount ?? 0
235
235
  })]
236
236
  }),
237
- /* @__PURE__ */ b("div", {
237
+ /* @__PURE__ */ y("div", {
238
238
  className: "flex justify-between",
239
- children: [/* @__PURE__ */ y("span", {
239
+ children: [/* @__PURE__ */ v("span", {
240
240
  className: "text-text-secondary",
241
241
  children: S("devportal.totalInstallsLabel", "Total installs")
242
- }), /* @__PURE__ */ y("span", {
242
+ }), /* @__PURE__ */ v("span", {
243
243
  className: "font-semibold",
244
244
  children: j?.totalInstalls ?? 0
245
245
  })]
246
246
  }),
247
- /* @__PURE__ */ b("div", {
247
+ /* @__PURE__ */ y("div", {
248
248
  className: "flex justify-between",
249
- children: [/* @__PURE__ */ y("span", {
249
+ children: [/* @__PURE__ */ v("span", {
250
250
  className: "text-text-secondary",
251
251
  children: S("devportal.avgRatingLabel", "Avg rating")
252
- }), /* @__PURE__ */ y("span", {
252
+ }), /* @__PURE__ */ v("span", {
253
253
  className: "font-semibold",
254
254
  children: j?.averageRating ? j.averageRating.toFixed(1) : "—"
255
255
  })]