@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":"ListingPreviewPage.js","names":["PRICING_LABELS","APP_TYPE_LABELS","ListingPreviewPage","useParams","useDevportal","useI18n","tr","value","t","key","fallback","useGetApplicationQuery","appId","app","data","useEffect","name","reg","loading","PageLayout","Loader2","error","Alert","screenshots","isPublished","PermissionGuard","navigate","basePath","Eye","CheckCircle","Star","Download","url","i","Markdown","Tag","tag","Globe","ExternalLink","FileText","Shield","PageSection","ok","label"],"sources":["../../../src/devportal/pages/ListingPreviewPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useEffect } from \"react\";\nimport { useParams } from \"react-router\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n Star,\n Download,\n Globe,\n FileText,\n Shield,\n ExternalLink,\n Tag,\n CheckCircle,\n Loader2,\n Eye,\n} from \"lucide-react\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { Alert } from \"../components/ConfirmDialog\";\nimport { Markdown } from \"@burdenoff/fe-libs/shared/components\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport { useGetApplicationQuery } from \"../../generated/global-operations\";\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nconst PRICING_LABELS: Record<string, string> = {\n FREE: \"Free\",\n FREEMIUM: \"Free with in-app purchases\",\n PAID: \"Paid\",\n ONE_TIME: \"One-time purchase\",\n SUBSCRIPTION: \"Subscription\",\n USAGE_BASED: \"Usage-based pricing\",\n ENTERPRISE: \"Enterprise pricing\",\n};\n\nconst APP_TYPE_LABELS: Record<string, string> = {\n WORKFLOW: \"Workflow\",\n WIDGET: \"Widget\",\n BOT: \"Bot / Chatbot\",\n API_INTEGRATION: \"API Integration\",\n INTEGRATION: \"Integration\",\n ANALYST: \"AI Analyst\",\n ASSISTANT: \"AI Assistant\",\n AUTOMATION: \"Automation\",\n SPECIALIST: \"AI Specialist\",\n WEB_APP: \"Web App\",\n MOBILE_APP: \"Mobile App\",\n DESKTOP_APP: \"Desktop App\",\n CLI_TOOL: \"CLI Tool\",\n SERVICE: \"Service\",\n};\n\n// ============================================================================\n// Listing Preview Page\n// ============================================================================\n\nexport const ListingPreviewPage: 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 { data, loading, error } = useGetApplicationQuery({\n variables: { id: appId! },\n skip: !appId,\n fetchPolicy: \"cache-and-network\",\n });\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 if (loading) {\n return (\n <PageLayout\n title={tr(\"devportal.marketplacePreview\", \"Marketplace Preview\")}\n description={tr(\"devportal.loading\", \"Loading...\")}\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=\"h-8 w-8 animate-spin text-text-secondary\" />\n </div>\n </PageLayout>\n );\n }\n\n if (error || !app) {\n return (\n <PageLayout\n title={tr(\"devportal.marketplacePreview\", \"Marketplace Preview\")}\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 {error?.message ??\n tr(\"devportal.applicationNotFound\", \"Application not found\")}\n </Alert>\n </PageLayout>\n );\n }\n\n const screenshots = Array.isArray(app.screenshots)\n ? (app.screenshots as string[])\n : [];\n\n const isPublished = app.status === \"PUBLISHED\";\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={tr(\"devportal.marketplacePreview\", \"Marketplace Preview\")}\n description={tr(\n \"devportal.marketplacePreviewDescription\",\n \"Preview how your app will appear in the marketplace\",\n )}\n purpose={tr(\n \"devportal.marketplacePreviewPurpose\",\n \"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.\",\n )}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n actions={\n !isPublished ? (\n <button\n onClick={() => navigate?.(`${basePath}/apps/${appId}/publish`)}\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 <Eye size={16} />\n {tr(\"devportal.submitForReview\", \"Submit for Review\")}\n </button>\n ) : undefined\n }\n >\n {/* Preview banner */}\n <div 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\">\n <Eye size={16} className=\"flex-shrink-0\" />\n <span>\n {tr(\n \"devportal.previewBannerText\",\n \"This is a preview of your marketplace listing. It shows how your app will appear to users after publication.\",\n )}\n </span>\n </div>\n\n {/* === Simulated marketplace product page === */}\n <div className=\"rounded-xl border bg-bg-surface overflow-hidden\">\n {/* Banner */}\n {app.bannerUrl ? (\n <div className=\"h-48 w-full overflow-hidden\">\n <img\n src={app.bannerUrl}\n alt={tr(\"devportal.appBannerAlt\", \"App banner\")}\n className=\"h-full w-full object-cover\"\n />\n </div>\n ) : (\n <div className=\"h-32 w-full bg-gradient-to-r from-primary/20 to-primary/5\" />\n )}\n\n {/* Hero */}\n <div className=\"p-6\">\n <div className=\"flex items-start gap-5\">\n {app.iconUrl ? (\n <img\n src={app.iconUrl}\n alt={app.name}\n className=\"h-20 w-20 rounded-2xl border object-cover flex-shrink-0 shadow-sm\"\n />\n ) : (\n <div className=\"h-20 w-20 rounded-2xl border bg-bg-sunken flex items-center justify-center flex-shrink-0\">\n <span\n className=\"text-3xl font-bold text-text-secondary\"\n aria-label={tr(\n \"devportal.appIconFallbackAriaLabel\",\n \"App icon\",\n )}\n >\n {app.name.charAt(0).toUpperCase()}\n </span>\n </div>\n )}\n\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h1 className=\"text-2xl font-bold\">{app.name}</h1>\n {app.isVerified && (\n <CheckCircle size={20} className=\"text-primary\" />\n )}\n {app.isFeatured && (\n <span className=\"rounded-full bg-status-warning-bg-subtle px-2 py-0.5 text-xs font-medium text-status-warning-text\">\n {tr(\"devportal.featured\", \"Featured\")}\n </span>\n )}\n </div>\n\n <p className=\"mt-1 text-text-secondary\">\n {app.shortDescription ??\n app.description ??\n tr(\"devportal.noDescription\", \"No description\")}\n </p>\n\n <div className=\"mt-3 flex flex-wrap items-center gap-4 text-sm text-text-secondary\">\n {app.averageRating != null && (\n <div className=\"flex items-center gap-1\">\n <Star\n size={14}\n className=\"text-status-warning-text fill-status-warning-text\"\n />\n <span className=\"font-medium text-text-primary\">\n {app.averageRating.toFixed(1)}\n </span>\n <span>\n ({app.reviewCount ?? 0}{\" \"}\n {tr(\"devportal.reviews\", \"reviews\")})\n </span>\n </div>\n )}\n <div className=\"flex items-center gap-1\">\n <Download size={14} />\n <span>\n {(app.installCount ?? 0).toLocaleString()}{\" \"}\n {tr(\"devportal.installs\", \"installs\")}\n </span>\n </div>\n {app.category && (\n <span className=\"rounded-full border px-2 py-0.5 text-xs\">\n {app.category}\n </span>\n )}\n <span className=\"rounded-full border px-2 py-0.5 text-xs\">\n {APP_TYPE_LABELS[app.appType] ?? app.appType}\n </span>\n </div>\n </div>\n\n {/* Install CTA (simulated) */}\n <div className=\"flex-shrink-0 text-right space-y-2\">\n <div className=\"text-lg font-semibold\">\n {PRICING_LABELS[app.pricingType ?? \"FREE\"] ?? \"Free\"}\n </div>\n <button\n disabled\n 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\"\n title={tr(\"devportal.previewOnly\", \"Preview only\")}\n >\n {tr(\"devportal.install\", \"Install\")}\n </button>\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.previewOnly\", \"Preview only\")}\n </p>\n </div>\n </div>\n </div>\n\n {/* Screenshots */}\n {screenshots.length > 0 && (\n <div className=\"border-t px-6 py-5\">\n <h2 className=\"text-base font-semibold mb-3\">\n {tr(\"devportal.screenshots\", \"Screenshots\")}\n </h2>\n <div className=\"flex gap-3 overflow-x-auto pb-2\">\n {screenshots.map((url, i) => (\n <img\n key={i}\n src={url}\n alt={`${tr(\"devportal.screenshotAlt\", \"Screenshot\")} ${i + 1}`}\n className=\"h-44 w-auto rounded-lg border object-cover flex-shrink-0\"\n />\n ))}\n </div>\n </div>\n )}\n\n {/* Description */}\n <div className=\"border-t px-6 py-5\">\n <h2 className=\"text-base font-semibold mb-2\">\n {tr(\"devportal.about\", \"About\")}\n </h2>\n {app.description || app.shortDescription ? (\n <Markdown className=\"text-sm text-text-secondary\">\n {app.description ?? app.shortDescription ?? \"\"}\n </Markdown>\n ) : (\n <p className=\"text-sm text-text-secondary\">\n {tr(\n \"devportal.noDetailedDescription\",\n \"No detailed description provided.\",\n )}\n </p>\n )}\n </div>\n\n {/* Tags */}\n {Array.isArray(app.tags) && app.tags.length > 0 && (\n <div className=\"border-t px-6 py-4\">\n <div className=\"flex flex-wrap gap-2\">\n {(app.tags as string[]).map((tag) => (\n <span\n key={tag}\n className=\"inline-flex items-center gap-1 rounded-full border px-3 py-1 text-xs text-text-secondary\"\n >\n <Tag size={10} />\n {tag}\n </span>\n ))}\n </div>\n </div>\n )}\n\n {/* Links & Compliance */}\n <div className=\"border-t px-6 py-5 grid grid-cols-1 sm:grid-cols-2 gap-4 text-sm\">\n {app.websiteUrl && (\n <a\n href={app.websiteUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 text-primary hover:underline\"\n >\n <Globe size={14} />\n {tr(\"devportal.website\", \"Website\")}\n <ExternalLink size={12} />\n </a>\n )}\n {app.documentationUrl && (\n <a\n href={app.documentationUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 text-primary hover:underline\"\n >\n <FileText size={14} />\n {tr(\"devportal.documentation\", \"Documentation\")}\n <ExternalLink size={12} />\n </a>\n )}\n {app.privacyPolicyUrl && (\n <a\n href={app.privacyPolicyUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 text-primary hover:underline\"\n >\n <Shield size={14} />\n {tr(\"devportal.privacyPolicy\", \"Privacy Policy\")}\n <ExternalLink size={12} />\n </a>\n )}\n {app.termsOfServiceUrl && (\n <a\n href={app.termsOfServiceUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 text-primary hover:underline\"\n >\n <FileText size={14} />\n {tr(\"devportal.termsOfService\", \"Terms of Service\")}\n <ExternalLink size={12} />\n </a>\n )}\n </div>\n </div>\n\n {/* Completeness tips */}\n <PageSection\n title={tr(\"devportal.listingCompleteness\", \"Listing Completeness\")}\n >\n <div className=\"space-y-2\">\n {[\n {\n label: tr(\"devportal.completenessAppIcon\", \"App icon\"),\n ok: !!app.iconUrl,\n },\n {\n label: tr(\"devportal.completenessBannerImage\", \"Banner image\"),\n ok: !!app.bannerUrl,\n },\n {\n label: tr(\n \"devportal.completenessShortDescription\",\n \"Short description\",\n ),\n ok: !!app.shortDescription,\n },\n {\n label: tr(\n \"devportal.completenessFullDescription\",\n \"Full description\",\n ),\n ok: !!app.description,\n },\n {\n label: tr(\n \"devportal.completenessScreenshots\",\n \"Screenshots (3+)\",\n ),\n ok: screenshots.length >= 3,\n },\n {\n label: tr(\"devportal.completenessCategory\", \"Category\"),\n ok: !!app.category,\n },\n {\n label: tr(\"devportal.completenessTags\", \"Tags\"),\n ok:\n Array.isArray(app.tags) && (app.tags as string[]).length > 0,\n },\n {\n label: tr(\n \"devportal.completenessPrivacyPolicy\",\n \"Privacy policy URL\",\n ),\n ok: !!app.privacyPolicyUrl,\n },\n {\n label: tr(\n \"devportal.completenessTermsOfService\",\n \"Terms of service URL\",\n ),\n ok: !!app.termsOfServiceUrl,\n },\n ].map(({ label, ok }) => (\n <div key={label} className=\"flex items-center gap-3 text-sm\">\n {ok ? (\n <CheckCircle\n size={16}\n className=\"text-status-success-text flex-shrink-0\"\n />\n ) : (\n <div className=\"h-4 w-4 rounded-full border-2 border-muted-foreground flex-shrink-0\" />\n )}\n <span\n className={ok ? \"text-text-primary\" : \"text-text-secondary\"}\n >\n {label}\n </span>\n </div>\n ))}\n </div>\n {!isPublished && (\n <button\n onClick={() => navigate?.(`${basePath}/apps/${appId}/edit`)}\n className=\"mt-4 rounded-md border px-3 py-1.5 text-sm hover:bg-bg-sunken\"\n >\n {tr(\n \"devportal.editToImproveListing\",\n \"Edit to improve listing →\",\n )}\n </button>\n )}\n </PageSection>\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"ListingPreviewPage.js","names":["PRICING_LABELS","APP_TYPE_LABELS","ListingPreviewPage","useParams","useDevportal","useI18n","tr","value","t","key","fallback","useGetApplicationQuery","appId","app","data","useEffect","name","reg","loading","PageLayout","Loader2","error","Alert","screenshots","isPublished","PermissionGuard","navigate","basePath","Eye","StoreImage","CheckCircle","Star","Download","url","i","StoreImagePlaceholder","Markdown","Tag","tag","Globe","ExternalLink","FileText","Shield","PageSection","ok","label"],"sources":["../../../src/devportal/pages/ListingPreviewPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useEffect } from \"react\";\nimport { useParams } from \"react-router\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n Star,\n Download,\n Globe,\n FileText,\n Shield,\n ExternalLink,\n Tag,\n CheckCircle,\n Loader2,\n Eye,\n} from \"lucide-react\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { Alert } from \"../components/ConfirmDialog\";\nimport { Markdown } from \"@burdenoff/fe-libs/shared/components\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport { useGetApplicationQuery } from \"../../generated/global-operations\";\nimport { StoreImage, StoreImagePlaceholder } from \"../components/StoreImage\";\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nconst PRICING_LABELS: Record<string, string> = {\n FREE: \"Free\",\n FREEMIUM: \"Free with in-app purchases\",\n PAID: \"Paid\",\n ONE_TIME: \"One-time purchase\",\n SUBSCRIPTION: \"Subscription\",\n USAGE_BASED: \"Usage-based pricing\",\n ENTERPRISE: \"Enterprise pricing\",\n};\n\nconst APP_TYPE_LABELS: Record<string, string> = {\n WORKFLOW: \"Workflow\",\n WIDGET: \"Widget\",\n BOT: \"Bot / Chatbot\",\n API_INTEGRATION: \"API Integration\",\n INTEGRATION: \"Integration\",\n ANALYST: \"AI Analyst\",\n ASSISTANT: \"AI Assistant\",\n AUTOMATION: \"Automation\",\n SPECIALIST: \"AI Specialist\",\n WEB_APP: \"Web App\",\n MOBILE_APP: \"Mobile App\",\n DESKTOP_APP: \"Desktop App\",\n CLI_TOOL: \"CLI Tool\",\n SERVICE: \"Service\",\n};\n\n// ============================================================================\n// Listing Preview Page\n// ============================================================================\n\nexport const ListingPreviewPage: 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 { data, loading, error } = useGetApplicationQuery({\n variables: { id: appId! },\n skip: !appId,\n fetchPolicy: \"cache-and-network\",\n });\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 if (loading) {\n return (\n <PageLayout\n title={tr(\"devportal.marketplacePreview\", \"Marketplace Preview\")}\n description={tr(\"devportal.loading\", \"Loading...\")}\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=\"h-8 w-8 animate-spin text-text-secondary\" />\n </div>\n </PageLayout>\n );\n }\n\n if (error || !app) {\n return (\n <PageLayout\n title={tr(\"devportal.marketplacePreview\", \"Marketplace Preview\")}\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 {error?.message ??\n tr(\"devportal.applicationNotFound\", \"Application not found\")}\n </Alert>\n </PageLayout>\n );\n }\n\n const screenshots = Array.isArray(app.screenshots)\n ? (app.screenshots as string[])\n : [];\n\n const isPublished = app.status === \"PUBLISHED\";\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={tr(\"devportal.marketplacePreview\", \"Marketplace Preview\")}\n description={tr(\n \"devportal.marketplacePreviewDescription\",\n \"Preview how your app will appear in the marketplace\",\n )}\n purpose={tr(\n \"devportal.marketplacePreviewPurpose\",\n \"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.\",\n )}\n backLink={`/apps/${appId}`}\n backLabel={tr(\"devportal.backToApplication\", \"Back to Application\")}\n actions={\n !isPublished ? (\n <button\n onClick={() => navigate?.(`${basePath}/apps/${appId}/publish`)}\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 <Eye size={16} />\n {tr(\"devportal.submitForReview\", \"Submit for Review\")}\n </button>\n ) : undefined\n }\n >\n {/* Preview banner */}\n <div 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\">\n <Eye size={16} className=\"flex-shrink-0\" />\n <span>\n {tr(\n \"devportal.previewBannerText\",\n \"This is a preview of your marketplace listing. It shows how your app will appear to users after publication.\",\n )}\n </span>\n </div>\n\n {/* === Simulated marketplace product page === */}\n <div className=\"rounded-xl border bg-bg-surface overflow-hidden\">\n {/* Banner */}\n <StoreImage\n src={app.bannerUrl}\n alt={tr(\"devportal.appBannerAlt\", \"App banner\")}\n className=\"block h-48 w-full object-cover\"\n fallback={\n <div className=\"h-32 w-full bg-gradient-to-r from-primary/20 to-primary/5\" />\n }\n />\n\n {/* Hero */}\n <div className=\"p-6\">\n <div className=\"flex items-start gap-5\">\n <StoreImage\n src={app.iconUrl}\n alt={app.name}\n className=\"h-20 w-20 rounded-2xl border object-cover flex-shrink-0 shadow-sm\"\n fallback={\n <div className=\"h-20 w-20 rounded-2xl border bg-bg-sunken flex items-center justify-center flex-shrink-0\">\n <span\n className=\"text-3xl font-bold text-text-secondary\"\n aria-label={tr(\n \"devportal.appIconFallbackAriaLabel\",\n \"App icon\",\n )}\n >\n {app.name.charAt(0).toUpperCase()}\n </span>\n </div>\n }\n />\n\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <h1 className=\"text-2xl font-bold\">{app.name}</h1>\n {app.isVerified && (\n <CheckCircle size={20} className=\"text-primary\" />\n )}\n {app.isFeatured && (\n <span className=\"rounded-full bg-status-warning-bg-subtle px-2 py-0.5 text-xs font-medium text-status-warning-text\">\n {tr(\"devportal.featured\", \"Featured\")}\n </span>\n )}\n </div>\n\n <p className=\"mt-1 text-text-secondary\">\n {app.shortDescription ??\n app.description ??\n tr(\"devportal.noDescription\", \"No description\")}\n </p>\n\n <div className=\"mt-3 flex flex-wrap items-center gap-4 text-sm text-text-secondary\">\n {app.averageRating != null && (\n <div className=\"flex items-center gap-1\">\n <Star\n size={14}\n className=\"text-status-warning-text fill-status-warning-text\"\n />\n <span className=\"font-medium text-text-primary\">\n {app.averageRating.toFixed(1)}\n </span>\n <span>\n ({app.reviewCount ?? 0}{\" \"}\n {tr(\"devportal.reviews\", \"reviews\")})\n </span>\n </div>\n )}\n <div className=\"flex items-center gap-1\">\n <Download size={14} />\n <span>\n {(app.installCount ?? 0).toLocaleString()}{\" \"}\n {tr(\"devportal.installs\", \"installs\")}\n </span>\n </div>\n {app.category && (\n <span className=\"rounded-full border px-2 py-0.5 text-xs\">\n {app.category}\n </span>\n )}\n <span className=\"rounded-full border px-2 py-0.5 text-xs\">\n {APP_TYPE_LABELS[app.appType] ?? app.appType}\n </span>\n </div>\n </div>\n\n {/* Install CTA (simulated) */}\n <div className=\"flex-shrink-0 text-right space-y-2\">\n <div className=\"text-lg font-semibold\">\n {PRICING_LABELS[app.pricingType ?? \"FREE\"] ?? \"Free\"}\n </div>\n <button\n disabled\n 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\"\n title={tr(\"devportal.previewOnly\", \"Preview only\")}\n >\n {tr(\"devportal.install\", \"Install\")}\n </button>\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.previewOnly\", \"Preview only\")}\n </p>\n </div>\n </div>\n </div>\n\n {/* Screenshots */}\n {screenshots.length > 0 && (\n <div className=\"border-t px-6 py-5\">\n <h2 className=\"text-base font-semibold mb-3\">\n {tr(\"devportal.screenshots\", \"Screenshots\")}\n </h2>\n <div className=\"flex gap-3 overflow-x-auto pb-2\">\n {screenshots.map((url, i) => (\n <StoreImage\n key={i}\n src={url}\n alt={`${tr(\"devportal.screenshotAlt\", \"Screenshot\")} ${i + 1}`}\n className=\"h-44 w-auto rounded-lg border object-cover flex-shrink-0\"\n fallback={\n <StoreImagePlaceholder\n className=\"h-44 w-72 rounded-lg\"\n iconSize={24}\n />\n }\n />\n ))}\n </div>\n </div>\n )}\n\n {/* Description */}\n <div className=\"border-t px-6 py-5\">\n <h2 className=\"text-base font-semibold mb-2\">\n {tr(\"devportal.about\", \"About\")}\n </h2>\n {app.description || app.shortDescription ? (\n <Markdown className=\"text-sm text-text-secondary\">\n {app.description ?? app.shortDescription ?? \"\"}\n </Markdown>\n ) : (\n <p className=\"text-sm text-text-secondary\">\n {tr(\n \"devportal.noDetailedDescription\",\n \"No detailed description provided.\",\n )}\n </p>\n )}\n </div>\n\n {/* Tags */}\n {Array.isArray(app.tags) && app.tags.length > 0 && (\n <div className=\"border-t px-6 py-4\">\n <div className=\"flex flex-wrap gap-2\">\n {(app.tags as string[]).map((tag) => (\n <span\n key={tag}\n className=\"inline-flex items-center gap-1 rounded-full border px-3 py-1 text-xs text-text-secondary\"\n >\n <Tag size={10} />\n {tag}\n </span>\n ))}\n </div>\n </div>\n )}\n\n {/* Links & Compliance */}\n <div className=\"border-t px-6 py-5 grid grid-cols-1 sm:grid-cols-2 gap-4 text-sm\">\n {app.websiteUrl && (\n <a\n href={app.websiteUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 text-primary hover:underline\"\n >\n <Globe size={14} />\n {tr(\"devportal.website\", \"Website\")}\n <ExternalLink size={12} />\n </a>\n )}\n {app.documentationUrl && (\n <a\n href={app.documentationUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 text-primary hover:underline\"\n >\n <FileText size={14} />\n {tr(\"devportal.documentation\", \"Documentation\")}\n <ExternalLink size={12} />\n </a>\n )}\n {app.privacyPolicyUrl && (\n <a\n href={app.privacyPolicyUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 text-primary hover:underline\"\n >\n <Shield size={14} />\n {tr(\"devportal.privacyPolicy\", \"Privacy Policy\")}\n <ExternalLink size={12} />\n </a>\n )}\n {app.termsOfServiceUrl && (\n <a\n href={app.termsOfServiceUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 text-primary hover:underline\"\n >\n <FileText size={14} />\n {tr(\"devportal.termsOfService\", \"Terms of Service\")}\n <ExternalLink size={12} />\n </a>\n )}\n </div>\n </div>\n\n {/* Completeness tips */}\n <PageSection\n title={tr(\"devportal.listingCompleteness\", \"Listing Completeness\")}\n >\n <div className=\"space-y-2\">\n {[\n {\n label: tr(\"devportal.completenessAppIcon\", \"App icon\"),\n ok: !!app.iconUrl,\n },\n {\n label: tr(\"devportal.completenessBannerImage\", \"Banner image\"),\n ok: !!app.bannerUrl,\n },\n {\n label: tr(\n \"devportal.completenessShortDescription\",\n \"Short description\",\n ),\n ok: !!app.shortDescription,\n },\n {\n label: tr(\n \"devportal.completenessFullDescription\",\n \"Full description\",\n ),\n ok: !!app.description,\n },\n {\n label: tr(\n \"devportal.completenessScreenshots\",\n \"Screenshots (3+)\",\n ),\n ok: screenshots.length >= 3,\n },\n {\n label: tr(\"devportal.completenessCategory\", \"Category\"),\n ok: !!app.category,\n },\n {\n label: tr(\"devportal.completenessTags\", \"Tags\"),\n ok:\n Array.isArray(app.tags) && (app.tags as string[]).length > 0,\n },\n {\n label: tr(\n \"devportal.completenessPrivacyPolicy\",\n \"Privacy policy URL\",\n ),\n ok: !!app.privacyPolicyUrl,\n },\n {\n label: tr(\n \"devportal.completenessTermsOfService\",\n \"Terms of service URL\",\n ),\n ok: !!app.termsOfServiceUrl,\n },\n ].map(({ label, ok }) => (\n <div key={label} className=\"flex items-center gap-3 text-sm\">\n {ok ? (\n <CheckCircle\n size={16}\n className=\"text-status-success-text flex-shrink-0\"\n />\n ) : (\n <div className=\"h-4 w-4 rounded-full border-2 border-muted-foreground flex-shrink-0\" />\n )}\n <span\n className={ok ? \"text-text-primary\" : \"text-text-secondary\"}\n >\n {label}\n </span>\n </div>\n ))}\n </div>\n {!isPublished && (\n <button\n onClick={() => navigate?.(`${basePath}/apps/${appId}/edit`)}\n className=\"mt-4 rounded-md border px-3 py-1.5 text-sm hover:bg-bg-sunken\"\n >\n {tr(\n \"devportal.editToImproveListing\",\n \"Edit to improve listing →\",\n )}\n </button>\n )}\n </PageSection>\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
@@ -7,20 +7,20 @@ import { errorMessage as s } from "../utils/errorMessage.js";
7
7
  import "../components/index.js";
8
8
  import { PermissionGuard as ne } from "../components/PermissionGuard.js";
9
9
  import { cn as re } from "../utils/cn.js";
10
- import { nativeCopyText as ie, nativeImpact as ae, nativeNotify as c } from "../../utils/nativeBridge.js";
10
+ import { nativeCopyText as ie, nativeImpact as ae, nativeNotify as oe } from "../../utils/nativeBridge.js";
11
11
  import "../hooks/index.js";
12
- import { useState as l } from "react";
13
- import { AlertCircle as u, ArrowLeft as d, Copy as f, Eye as p, EyeOff as m, Loader2 as h, RefreshCw as g, Trash2 as oe } from "lucide-react";
14
- import { useParams as _ } from "react-router";
15
- import { jsx as v, jsxs as y } from "react/jsx-runtime";
16
- import { useI18n as se } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
17
- import { AlertDialog as b, AlertDialogAction as x, AlertDialogCancel as S, AlertDialogContent as C, AlertDialogDescription as w, AlertDialogFooter as T, AlertDialogHeader as E, AlertDialogTitle as D, CTAOverflowMenu as O, GlassCard as k } from "@burdenoff/fe-libs/ui";
12
+ import { useState as c } from "react";
13
+ import { AlertCircle as l, ArrowLeft as u, Copy as d, Eye as f, EyeOff as p, Loader2 as m, RefreshCw as h, Trash2 as se } from "lucide-react";
14
+ import { useParams as g } from "react-router";
15
+ import { jsx as _, jsxs as v } from "react/jsx-runtime";
16
+ import { AlertDialog as y, AlertDialogAction as b, AlertDialogCancel as x, AlertDialogContent as S, AlertDialogDescription as C, AlertDialogFooter as w, AlertDialogHeader as T, AlertDialogTitle as E, CTAOverflowMenu as D, GlassCard as O } from "@burdenoff/fe-libs/ui";
17
+ import { useI18n as k } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
18
18
  // src/devportal/pages/OAuthClientDetailPage.tsx
19
19
  var A = () => {
20
- let { clientId: A } = _(), { navigate: j, basePath: M } = o(), { t: N } = se(), P = (e, t) => {
20
+ let { clientId: A } = g(), { navigate: j, basePath: M } = o(), { t: N } = k(), P = (e, t) => {
21
21
  let n = N(e);
22
22
  return n === e ? t : n;
23
- }, [F, I] = l(!1), [L, R] = l(null), [z, B] = l(!1), [V, H] = l(!1), [U, W] = l(null), G = te(), { data: K, loading: ce, error: q, refetch: J } = ee({
23
+ }, [F, I] = c(!1), [L, R] = c(null), [z, B] = c(!1), [V, H] = c(!1), [U, W] = c(null), G = te(), { data: K, loading: ce, error: q, refetch: J } = ee({
24
24
  variables: { id: A || "" },
25
25
  skip: !A,
26
26
  fetchPolicy: "cache-and-network"
@@ -42,7 +42,7 @@ var A = () => {
42
42
  }, $ = async (e) => {
43
43
  ae("light");
44
44
  let t = await ie(e);
45
- c(t ? "success" : "error");
45
+ oe(t ? "success" : "error");
46
46
  }, fe = async () => {
47
47
  if (A) {
48
48
  W(null);
@@ -63,48 +63,48 @@ var A = () => {
63
63
  }
64
64
  }
65
65
  };
66
- return ce && !K ? /* @__PURE__ */ v(e, {
66
+ return ce && !K ? /* @__PURE__ */ _(e, {
67
67
  title: P("devportal.appDetails", "App Details"),
68
68
  description: P("devportal.loadingDots", "Loading..."),
69
69
  backLink: "/oauth",
70
70
  backLabel: P("devportal.backToApps", "Back to Apps"),
71
- children: /* @__PURE__ */ v("div", {
71
+ children: /* @__PURE__ */ _("div", {
72
72
  className: "flex items-center justify-center py-12",
73
- children: /* @__PURE__ */ v(h, { className: "h-8 w-8 animate-spin text-text-secondary" })
73
+ children: /* @__PURE__ */ _(m, { className: "h-8 w-8 animate-spin text-text-secondary" })
74
74
  })
75
- }) : q || !Z ? /* @__PURE__ */ v(e, {
75
+ }) : q || !Z ? /* @__PURE__ */ _(e, {
76
76
  title: P("devportal.appDetails", "App Details"),
77
77
  description: P("devportal.failedToLoad", "Failed to load"),
78
78
  backLink: "/oauth",
79
79
  backLabel: P("devportal.backToApps", "Back to Apps"),
80
- children: /* @__PURE__ */ y("div", {
80
+ children: /* @__PURE__ */ v("div", {
81
81
  className: "rounded-lg border border-status-error-border/50 bg-status-error-bg/10 p-6 text-center",
82
82
  children: [
83
- /* @__PURE__ */ v(u, { className: "mx-auto h-8 w-8 text-status-error-text" }),
84
- /* @__PURE__ */ v("h3", {
83
+ /* @__PURE__ */ _(l, { className: "mx-auto h-8 w-8 text-status-error-text" }),
84
+ /* @__PURE__ */ _("h3", {
85
85
  className: "mt-2 font-medium text-status-error-text",
86
86
  children: q ? P("devportal.failedToLoadApp", "Failed to load app") : P("devportal.appNotFound", "App not found")
87
87
  }),
88
- q && /* @__PURE__ */ v("p", {
88
+ q && /* @__PURE__ */ _("p", {
89
89
  className: "mt-1 text-sm text-text-secondary",
90
90
  children: a(q)
91
91
  }),
92
- /* @__PURE__ */ y("button", {
92
+ /* @__PURE__ */ v("button", {
93
93
  onClick: () => Q("/oauth"),
94
94
  className: "mt-4 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",
95
- children: [/* @__PURE__ */ v(d, { size: 16 }), P("devportal.backToApps", "Back to Apps")]
95
+ children: [/* @__PURE__ */ _(u, { size: 16 }), P("devportal.backToApps", "Back to Apps")]
96
96
  })
97
97
  ]
98
98
  })
99
- }) : /* @__PURE__ */ v(ne, {
99
+ }) : /* @__PURE__ */ _(ne, {
100
100
  authOnly: !0,
101
- children: /* @__PURE__ */ y(e, {
101
+ children: /* @__PURE__ */ v(e, {
102
102
  title: Z.name,
103
103
  description: Z.description || P("devportal.oauthAppDetailsAndCredentials", "OAuth App details and credentials"),
104
104
  purpose: P("devportal.oauthAppDetailPurpose", "These are this OAuth app's credentials and the scopes it may request. Copy the client ID for your integration, rotate the secret if it leaks, and keep scopes minimal so users only grant what the app truly needs."),
105
105
  backLink: "/oauth",
106
106
  backLabel: P("devportal.backToApps", "Back to Apps"),
107
- actions: /* @__PURE__ */ v(O, {
107
+ actions: /* @__PURE__ */ _(D, {
108
108
  primary: {
109
109
  label: Z.status === "ACTIVE" ? P("devportal.deactivate", "Deactivate") : P("devportal.activate", "Activate"),
110
110
  onSelect: async () => {
@@ -123,114 +123,114 @@ var A = () => {
123
123
  },
124
124
  actions: [{
125
125
  label: G ? P("devportal.deactivate", "Deactivate") : P("devportal.delete", "Delete"),
126
- icon: /* @__PURE__ */ v(oe, { size: 16 }),
126
+ icon: /* @__PURE__ */ _(se, { size: 16 }),
127
127
  intent: "destructive",
128
128
  onSelect: () => B(!0)
129
129
  }]
130
130
  }),
131
131
  children: [
132
- U && /* @__PURE__ */ v("div", {
132
+ U && /* @__PURE__ */ _("div", {
133
133
  role: "alert",
134
134
  className: "mb-4 rounded-md bg-status-error-bg px-3 py-2 text-sm text-status-error-text",
135
135
  children: U
136
136
  }),
137
- /* @__PURE__ */ y("div", {
137
+ /* @__PURE__ */ v("div", {
138
138
  className: "grid gap-6 md:grid-cols-2",
139
- children: [/* @__PURE__ */ y("div", {
139
+ children: [/* @__PURE__ */ v("div", {
140
140
  className: "rounded-card border border-border-seam bg-bg-surface p-6",
141
- children: [/* @__PURE__ */ v("h3", {
141
+ children: [/* @__PURE__ */ _("h3", {
142
142
  className: "text-sm font-medium text-text-secondary mb-4",
143
143
  children: P("devportal.statusAndConfiguration", "Status & Configuration")
144
- }), /* @__PURE__ */ y("div", {
144
+ }), /* @__PURE__ */ v("div", {
145
145
  className: "space-y-3",
146
146
  children: [
147
- /* @__PURE__ */ y("div", {
147
+ /* @__PURE__ */ v("div", {
148
148
  className: "flex justify-between",
149
- children: [/* @__PURE__ */ v("span", {
149
+ children: [/* @__PURE__ */ _("span", {
150
150
  className: "text-sm text-text-secondary",
151
151
  children: P("devportal.status", "Status")
152
- }), /* @__PURE__ */ y("div", {
152
+ }), /* @__PURE__ */ v("div", {
153
153
  className: "flex items-center gap-2",
154
- children: [/* @__PURE__ */ v(t, { active: Z.status === "ACTIVE" }), /* @__PURE__ */ v("span", {
154
+ children: [/* @__PURE__ */ _(t, { active: Z.status === "ACTIVE" }), /* @__PURE__ */ _("span", {
155
155
  className: "text-sm font-medium",
156
156
  children: Z.status
157
157
  })]
158
158
  })]
159
159
  }),
160
- /* @__PURE__ */ y("div", {
160
+ /* @__PURE__ */ v("div", {
161
161
  className: "flex justify-between",
162
- children: [/* @__PURE__ */ v("span", {
162
+ children: [/* @__PURE__ */ _("span", {
163
163
  className: "text-sm text-text-secondary",
164
164
  children: P("devportal.type", "Type")
165
- }), /* @__PURE__ */ v("span", {
165
+ }), /* @__PURE__ */ _("span", {
166
166
  className: re("rounded px-2 py-0.5 text-xs font-medium", Z.type === "SERVICE" ? "bg-accent-purple-subtle text-accent-purple" : Z.type === "INTEGRATION" || Z.type === "API_INTEGRATION" ? "bg-status-info-bg-subtle text-status-info-text" : "bg-status-success-bg-subtle text-status-success-text"),
167
167
  children: Z.type
168
168
  })]
169
169
  }),
170
- /* @__PURE__ */ y("div", {
170
+ /* @__PURE__ */ v("div", {
171
171
  className: "flex justify-between",
172
- children: [/* @__PURE__ */ v("span", {
172
+ children: [/* @__PURE__ */ _("span", {
173
173
  className: "text-sm text-text-secondary",
174
174
  children: P("devportal.created", "Created")
175
- }), /* @__PURE__ */ v("span", {
175
+ }), /* @__PURE__ */ _("span", {
176
176
  className: "text-sm",
177
177
  children: new Date(Z.createdAt).toLocaleDateString()
178
178
  })]
179
179
  })
180
180
  ]
181
181
  })]
182
- }), /* @__PURE__ */ y(k, {
182
+ }), /* @__PURE__ */ v(O, {
183
183
  treatment: "glass",
184
184
  glow: !0,
185
185
  className: "p-6",
186
- children: [/* @__PURE__ */ v("h3", {
186
+ children: [/* @__PURE__ */ _("h3", {
187
187
  className: "text-sm font-medium text-text-secondary mb-4",
188
188
  children: P("devportal.credentials", "Credentials")
189
- }), /* @__PURE__ */ y("div", {
189
+ }), /* @__PURE__ */ v("div", {
190
190
  className: "space-y-3",
191
191
  children: [
192
- /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
192
+ /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("label", {
193
193
  className: "text-xs text-text-secondary",
194
194
  children: P("devportal.clientId", "Client ID")
195
- }), /* @__PURE__ */ y("div", {
195
+ }), /* @__PURE__ */ v("div", {
196
196
  className: "mt-1 flex items-center gap-2",
197
- children: [/* @__PURE__ */ v("code", {
197
+ children: [/* @__PURE__ */ _("code", {
198
198
  className: "flex-1 rounded bg-bg-sunken px-3 py-1.5 text-sm font-mono",
199
199
  children: Z.clientId
200
- }), /* @__PURE__ */ v("button", {
200
+ }), /* @__PURE__ */ _("button", {
201
201
  onClick: () => $(Z.clientId),
202
202
  className: "rounded p-1.5 hover:bg-bg-sunken transition-colors",
203
203
  title: "Copy",
204
- children: /* @__PURE__ */ v(f, { size: 14 })
204
+ children: /* @__PURE__ */ _(d, { size: 14 })
205
205
  })]
206
206
  })] }),
207
- L && /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
207
+ L && /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("label", {
208
208
  className: "text-xs text-status-error-text font-medium",
209
209
  children: P("devportal.newClientSecretShownOnce", "New Client Secret (shown only once!)")
210
- }), /* @__PURE__ */ y("div", {
210
+ }), /* @__PURE__ */ v("div", {
211
211
  className: "mt-1 flex items-center gap-2",
212
212
  children: [
213
- /* @__PURE__ */ v("code", {
213
+ /* @__PURE__ */ _("code", {
214
214
  className: "flex-1 rounded bg-status-error-bg/10 border border-status-error-border/30 px-3 py-1.5 text-sm font-mono",
215
215
  children: F ? L : "••••••••••••••••"
216
216
  }),
217
- /* @__PURE__ */ v("button", {
217
+ /* @__PURE__ */ _("button", {
218
218
  onClick: () => I(!F),
219
219
  className: "rounded p-1.5 hover:bg-bg-sunken transition-colors",
220
- children: v(F ? m : p, { size: 14 })
220
+ children: _(F ? p : f, { size: 14 })
221
221
  }),
222
- /* @__PURE__ */ v("button", {
222
+ /* @__PURE__ */ _("button", {
223
223
  onClick: () => $(L),
224
224
  className: "rounded p-1.5 hover:bg-bg-sunken transition-colors",
225
- children: /* @__PURE__ */ v(f, { size: 14 })
225
+ children: /* @__PURE__ */ _(d, { size: 14 })
226
226
  })
227
227
  ]
228
228
  })] }),
229
- /* @__PURE__ */ y("button", {
229
+ /* @__PURE__ */ v("button", {
230
230
  onClick: () => H(!0),
231
231
  disabled: Y,
232
232
  className: "mt-2 inline-flex items-center gap-2 rounded-md bg-status-warning-bg-subtle px-3 py-1.5 text-sm font-medium text-status-warning-text hover:bg-status-warning-bg-subtle transition-colors disabled:opacity-50",
233
- children: [/* @__PURE__ */ v(g, {
233
+ children: [/* @__PURE__ */ _(h, {
234
234
  size: 14,
235
235
  className: Y ? "animate-spin" : ""
236
236
  }), P("devportal.rotateSecret", "Rotate Secret")]
@@ -239,9 +239,9 @@ var A = () => {
239
239
  })]
240
240
  })]
241
241
  }),
242
- /* @__PURE__ */ y("div", {
242
+ /* @__PURE__ */ v("div", {
243
243
  className: "rounded-card border border-border-seam bg-bg-surface p-6",
244
- children: [/* @__PURE__ */ y("h3", {
244
+ children: [/* @__PURE__ */ v("h3", {
245
245
  className: "text-sm font-medium text-text-secondary mb-3",
246
246
  children: [
247
247
  P("devportal.scopes", "Scopes"),
@@ -249,20 +249,20 @@ var A = () => {
249
249
  Z.scopes.length,
250
250
  ")"
251
251
  ]
252
- }), Z.scopes.length > 0 ? /* @__PURE__ */ v("div", {
252
+ }), Z.scopes.length > 0 ? /* @__PURE__ */ _("div", {
253
253
  className: "flex flex-wrap gap-2",
254
- children: Z.scopes.map((e) => /* @__PURE__ */ v("span", {
254
+ children: Z.scopes.map((e) => /* @__PURE__ */ _("span", {
255
255
  className: "rounded-full bg-action-primary-bg/10 px-3 py-1 text-xs font-medium text-primary",
256
256
  children: e
257
257
  }, e))
258
- }) : /* @__PURE__ */ v("p", {
258
+ }) : /* @__PURE__ */ _("p", {
259
259
  className: "text-sm text-text-secondary",
260
260
  children: P("devportal.noScopesConfigured", "No scopes configured")
261
261
  })]
262
262
  }),
263
- /* @__PURE__ */ y("div", {
263
+ /* @__PURE__ */ v("div", {
264
264
  className: "rounded-card border border-border-seam bg-bg-surface p-6",
265
- children: [/* @__PURE__ */ y("h3", {
265
+ children: [/* @__PURE__ */ v("h3", {
266
266
  className: "text-sm font-medium text-text-secondary mb-3",
267
267
  children: [
268
268
  P("devportal.redirectUris", "Redirect URIs"),
@@ -270,31 +270,31 @@ var A = () => {
270
270
  Z.redirectUris.length,
271
271
  ")"
272
272
  ]
273
- }), Z.redirectUris.length > 0 ? /* @__PURE__ */ v("div", {
273
+ }), Z.redirectUris.length > 0 ? /* @__PURE__ */ _("div", {
274
274
  className: "space-y-2",
275
- children: Z.redirectUris.map((e) => /* @__PURE__ */ y("div", {
275
+ children: Z.redirectUris.map((e) => /* @__PURE__ */ v("div", {
276
276
  className: "flex items-center gap-2",
277
- children: [/* @__PURE__ */ v("code", {
277
+ children: [/* @__PURE__ */ _("code", {
278
278
  className: "rounded bg-bg-sunken px-3 py-1.5 text-sm font-mono",
279
279
  children: e
280
- }), /* @__PURE__ */ v("button", {
280
+ }), /* @__PURE__ */ _("button", {
281
281
  onClick: () => $(e),
282
282
  className: "rounded p-1 hover:bg-bg-sunken transition-colors",
283
- children: /* @__PURE__ */ v(f, { size: 12 })
283
+ children: /* @__PURE__ */ _(d, { size: 12 })
284
284
  })]
285
285
  }, e))
286
- }) : /* @__PURE__ */ v("p", {
286
+ }) : /* @__PURE__ */ _("p", {
287
287
  className: "text-sm text-text-secondary",
288
288
  children: P("devportal.noRedirectUrisConfigured", "No redirect URIs configured")
289
289
  })]
290
290
  }),
291
- /* @__PURE__ */ v(b, {
291
+ /* @__PURE__ */ _(y, {
292
292
  open: V,
293
293
  onOpenChange: H,
294
- children: /* @__PURE__ */ y(C, { children: [/* @__PURE__ */ y(E, { children: [/* @__PURE__ */ v(D, { children: P("devportal.rotateClientSecretQuestion", "Rotate Client Secret?") }), /* @__PURE__ */ v(w, { children: P("devportal.rotateSecretWarning", "This will invalidate the current client secret. All integrations using the old secret will stop working immediately.") })] }), /* @__PURE__ */ y(T, { children: [/* @__PURE__ */ v(S, {
294
+ children: /* @__PURE__ */ v(S, { children: [/* @__PURE__ */ v(T, { children: [/* @__PURE__ */ _(E, { children: P("devportal.rotateClientSecretQuestion", "Rotate Client Secret?") }), /* @__PURE__ */ _(C, { children: P("devportal.rotateSecretWarning", "This will invalidate the current client secret. All integrations using the old secret will stop working immediately.") })] }), /* @__PURE__ */ v(w, { children: [/* @__PURE__ */ _(x, {
295
295
  disabled: Y,
296
296
  children: P("devportal.cancel", "Cancel")
297
- }), /* @__PURE__ */ v(x, {
297
+ }), /* @__PURE__ */ _(b, {
298
298
  onClick: (e) => {
299
299
  e.preventDefault(), fe();
300
300
  },
@@ -303,16 +303,16 @@ var A = () => {
303
303
  children: Y ? P("devportal.rotating", "Rotating...") : P("devportal.rotateSecret", "Rotate Secret")
304
304
  })] })] })
305
305
  }),
306
- /* @__PURE__ */ v(b, {
306
+ /* @__PURE__ */ _(y, {
307
307
  open: z,
308
308
  onOpenChange: B,
309
- children: /* @__PURE__ */ y(C, { children: [/* @__PURE__ */ y(E, { children: [/* @__PURE__ */ v(D, {
309
+ children: /* @__PURE__ */ v(S, { children: [/* @__PURE__ */ v(T, { children: [/* @__PURE__ */ _(E, {
310
310
  className: "text-status-error-text",
311
311
  children: P("devportal.deactivateAppQuestion", "Deactivate App?")
312
- }), /* @__PURE__ */ v(w, { children: P("devportal.deactivateAppWarning", "This will deactivate the app and revoke all tokens. This action cannot be undone easily.") })] }), /* @__PURE__ */ y(T, { children: [/* @__PURE__ */ v(S, {
312
+ }), /* @__PURE__ */ _(C, { children: P("devportal.deactivateAppWarning", "This will deactivate the app and revoke all tokens. This action cannot be undone easily.") })] }), /* @__PURE__ */ v(w, { children: [/* @__PURE__ */ _(x, {
313
313
  disabled: X,
314
314
  children: P("devportal.cancel", "Cancel")
315
- }), /* @__PURE__ */ v(x, {
315
+ }), /* @__PURE__ */ _(b, {
316
316
  onClick: (e) => {
317
317
  e.preventDefault(), pe();
318
318
  },