@burdenoff/microfe-devportal 2026.717.1 → 2026.720.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/devportal/components/PermissionGuard.d.ts +14 -1
  2. package/dist/devportal/components/PermissionGuard.d.ts.map +1 -1
  3. package/dist/devportal/components/PermissionGuard.js +16 -13
  4. package/dist/devportal/components/PermissionGuard.js.map +1 -1
  5. package/dist/devportal/pages/AdminReviewPage.js +9 -9
  6. package/dist/devportal/pages/ApiKeysPage.js +180 -181
  7. package/dist/devportal/pages/ApiKeysPage.js.map +1 -1
  8. package/dist/devportal/pages/ApplicationDetailPage.js +3 -3
  9. package/dist/devportal/pages/ApplicationVersionsPage.js +4 -4
  10. package/dist/devportal/pages/ApplicationVersionsPage.js.map +1 -1
  11. package/dist/devportal/pages/ApplicationsPage.js +4 -4
  12. package/dist/devportal/pages/ApplicationsPage.js.map +1 -1
  13. package/dist/devportal/pages/CreateApiKeyPage.js +1 -1
  14. package/dist/devportal/pages/CreateOAuthClientPage.js +1 -1
  15. package/dist/devportal/pages/CreateOrganizationPage.js +1 -1
  16. package/dist/devportal/pages/CreateWebhookPage.js +25 -25
  17. package/dist/devportal/pages/DashboardPage.d.ts.map +1 -1
  18. package/dist/devportal/pages/DashboardPage.js +110 -111
  19. package/dist/devportal/pages/DashboardPage.js.map +1 -1
  20. package/dist/devportal/pages/DelegationsPage.js +1 -1
  21. package/dist/devportal/pages/EditApplicationPage.js +4 -4
  22. package/dist/devportal/pages/ListingPreviewPage.d.ts.map +1 -1
  23. package/dist/devportal/pages/ListingPreviewPage.js +160 -161
  24. package/dist/devportal/pages/ListingPreviewPage.js.map +1 -1
  25. package/dist/devportal/pages/OAuthClientDetailPage.d.ts.map +1 -1
  26. package/dist/devportal/pages/OAuthClientDetailPage.js +166 -167
  27. package/dist/devportal/pages/OAuthClientDetailPage.js.map +1 -1
  28. package/dist/devportal/pages/OAuthClientsPage.d.ts.map +1 -1
  29. package/dist/devportal/pages/OAuthClientsPage.js +121 -122
  30. package/dist/devportal/pages/OAuthClientsPage.js.map +1 -1
  31. package/dist/devportal/pages/OrganizationDetailPage.js +3 -3
  32. package/dist/devportal/pages/OrganizationMembersPage.js +4 -4
  33. package/dist/devportal/pages/OrganizationsPage.js +1 -1
  34. package/dist/devportal/pages/PublishPage.js +246 -246
  35. package/dist/devportal/pages/PublishPage.js.map +1 -1
  36. package/dist/devportal/pages/PublisherProfilePage.js +4 -4
  37. package/dist/devportal/pages/PublisherProfilePage.js.map +1 -1
  38. package/dist/devportal/pages/StoreSubmissionPage.js +3 -3
  39. package/dist/devportal/pages/WebhookDetailPage.js +3 -3
  40. package/dist/devportal/pages/WebhooksPage.js +129 -129
  41. package/dist/devportal/pages/WebhooksPage.js.map +1 -1
  42. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ListingPreviewPage.js","names":[],"sources":["../../../src/devportal/pages/ListingPreviewPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useEffect } from \"react\";\nimport { useParams } from \"react-router-dom\";\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 { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport { DEVPORTAL_PERMISSIONS } from \"../constants/permissions\";\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 permission={DEVPORTAL_PERMISSIONS.APP_READ}>\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 <p className=\"text-sm text-text-secondary whitespace-pre-wrap\">\n {app.description ??\n app.shortDescription ??\n tr(\n \"devportal.noDetailedDescription\",\n \"No detailed description provided.\",\n )}\n </p>\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":[],"sources":["../../../src/devportal/pages/ListingPreviewPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useEffect } from \"react\";\nimport { useParams } from \"react-router-dom\";\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 { 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 <p className=\"text-sm text-text-secondary whitespace-pre-wrap\">\n {app.description ??\n app.shortDescription ??\n tr(\n \"devportal.noDetailedDescription\",\n \"No detailed description provided.\",\n )}\n </p>\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 +1 @@
1
- {"version":3,"file":"OAuthClientDetailPage.d.ts","sourceRoot":"","sources":["../../../src/devportal/pages/OAuthClientDetailPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AA8ChC;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,EA8ZnC,CAAC"}
1
+ {"version":3,"file":"OAuthClientDetailPage.d.ts","sourceRoot":"","sources":["../../../src/devportal/pages/OAuthClientDetailPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AA6ChC;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,EA8ZnC,CAAC"}
@@ -1,304 +1,303 @@
1
1
  import { useDevportal as e } from "../providers/DevportalProvider.js";
2
2
  import { cn as t } from "../utils/cn.js";
3
- import { useDeactivateAppMutation as n, useGetAuthAppQuery as ee, useRotateAppSecretMutation as r, useUpdateAuthAppMutation as i } from "../../generated/global-operations.js";
4
- import { getErrorMessage as a } from "../hooks/useGraphQL.js";
3
+ import { useDeactivateAppMutation as n, useGetAuthAppQuery as r, useRotateAppSecretMutation as i, useUpdateAuthAppMutation as a } from "../../generated/global-operations.js";
4
+ import { getErrorMessage as ee } from "../hooks/useGraphQL.js";
5
5
  import { PageLayout as o } from "../components/PageLayout.js";
6
6
  import { ActiveIndicator as te } from "../components/StatusBadge.js";
7
- import { nativeCopyText as ne, nativeImpact as re, nativeNotify as ie } from "../../utils/nativeBridge.js";
8
- import { PermissionGuard as ae } from "../components/PermissionGuard.js";
7
+ import { nativeCopyText as s, nativeImpact as c, nativeNotify as l } from "../../utils/nativeBridge.js";
8
+ import { PermissionGuard as ne } from "../components/PermissionGuard.js";
9
9
  import "../components/index.js";
10
- import { DEVPORTAL_PERMISSIONS as s } from "../constants/permissions.js";
11
10
  import "../hooks/index.js";
12
- import { useState as c } from "react";
13
- import { useI18n as l } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
14
- import { AlertCircle as u, ArrowLeft as d, Copy as f, Eye as p, EyeOff as m, Loader2 as h, RefreshCw as g, Trash2 as _ } from "lucide-react";
15
- import { useParams as v } from "react-router-dom";
16
- import { jsx as y, jsxs as b } from "react/jsx-runtime";
17
- import { AlertDialog as x, AlertDialogAction as S, AlertDialogCancel as C, AlertDialogContent as w, AlertDialogDescription as T, AlertDialogFooter as E, AlertDialogHeader as D, AlertDialogTitle as O, CTAOverflowMenu as k, GlassCard as A } from "@burdenoff/fe-libs/ui";
11
+ import { useState as u } from "react";
12
+ import { useI18n as re } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
13
+ import { AlertCircle as ie, ArrowLeft as ae, Copy as d, Eye as f, EyeOff as p, Loader2 as m, RefreshCw as h, Trash2 as g } from "lucide-react";
14
+ import { useParams as _ } from "react-router-dom";
15
+ import { jsx as v, jsxs as y } from "react/jsx-runtime";
16
+ 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";
18
17
  //#region src/devportal/pages/OAuthClientDetailPage.tsx
19
- var j = () => {
20
- let { clientId: j } = v(), { navigate: M, basePath: N } = e(), { t: P } = l(), F = (e, t) => {
21
- let n = P(e);
18
+ var A = () => {
19
+ let { clientId: A } = _(), { navigate: j, basePath: M } = e(), { t: N } = re(), P = (e, t) => {
20
+ let n = N(e);
22
21
  return n === e ? t : n;
23
- }, [I, L] = c(!1), [R, z] = c(null), [B, V] = c(!1), [H, U] = c(!1), { data: W, loading: G, error: K, refetch: q } = ee({
24
- variables: { id: j || "" },
25
- skip: !j,
22
+ }, [F, I] = u(!1), [L, R] = u(null), [z, B] = u(!1), [V, H] = u(!1), { data: U, loading: W, error: G, refetch: K } = r({
23
+ variables: { id: A || "" },
24
+ skip: !A,
26
25
  fetchPolicy: "cache-and-network"
27
- }), [oe, { loading: J }] = r(), [se, { loading: Y }] = n(), [ce] = i(), X = W?.app ? {
28
- id: W.app.id,
29
- name: W.app.name,
30
- description: W.app.description ?? void 0,
31
- clientId: W.app.clientId,
32
- type: W.app.type,
33
- status: W.app.status,
34
- scopes: W.app.scopes ?? [],
35
- redirectUris: W.app.redirectUris ?? [],
36
- ownerUserId: W.app.ownerUserId,
37
- tenantId: W.app.tenantId,
38
- createdAt: W.app.createdAt,
39
- updatedAt: W.app.updatedAt
40
- } : null, Z = (e) => {
41
- M?.(`${N}${e}`);
42
- }, Q = async (e) => {
43
- re("light"), ie(await ne(e) ? "success" : "error");
44
- }, le = async () => {
45
- if (j) try {
46
- let e = (await oe({ variables: { id: j } })).data?.rotateAppSecret?.clientSecret;
47
- e && (z(e), L(!0)), U(!1), q();
26
+ }), [q, { loading: J }] = i(), [Y, { loading: X }] = n(), [oe] = a(), Z = U?.app ? {
27
+ id: U.app.id,
28
+ name: U.app.name,
29
+ description: U.app.description ?? void 0,
30
+ clientId: U.app.clientId,
31
+ type: U.app.type,
32
+ status: U.app.status,
33
+ scopes: U.app.scopes ?? [],
34
+ redirectUris: U.app.redirectUris ?? [],
35
+ ownerUserId: U.app.ownerUserId,
36
+ tenantId: U.app.tenantId,
37
+ createdAt: U.app.createdAt,
38
+ updatedAt: U.app.updatedAt
39
+ } : null, Q = (e) => {
40
+ j?.(`${M}${e}`);
41
+ }, $ = async (e) => {
42
+ c("light"), l(await s(e) ? "success" : "error");
43
+ }, se = async () => {
44
+ if (A) try {
45
+ let e = (await q({ variables: { id: A } })).data?.rotateAppSecret?.clientSecret;
46
+ e && (R(e), I(!0)), H(!1), K();
48
47
  } catch {}
49
- }, $ = async () => {
50
- if (j) try {
51
- await se({ variables: { id: j } }), V(!1), Z("/oauth");
48
+ }, ce = async () => {
49
+ if (A) try {
50
+ await Y({ variables: { id: A } }), B(!1), Q("/oauth");
52
51
  } catch {}
53
52
  };
54
- return G && !W ? /* @__PURE__ */ y(o, {
55
- title: F("devportal.appDetails", "App Details"),
56
- description: F("devportal.loadingDots", "Loading..."),
53
+ return W && !U ? /* @__PURE__ */ v(o, {
54
+ title: P("devportal.appDetails", "App Details"),
55
+ description: P("devportal.loadingDots", "Loading..."),
57
56
  backLink: "/oauth",
58
- backLabel: F("devportal.backToApps", "Back to Apps"),
59
- children: /* @__PURE__ */ y("div", {
57
+ backLabel: P("devportal.backToApps", "Back to Apps"),
58
+ children: /* @__PURE__ */ v("div", {
60
59
  className: "flex items-center justify-center py-12",
61
- children: /* @__PURE__ */ y(h, { className: "h-8 w-8 animate-spin text-text-secondary" })
60
+ children: /* @__PURE__ */ v(m, { className: "h-8 w-8 animate-spin text-text-secondary" })
62
61
  })
63
- }) : K || !X ? /* @__PURE__ */ y(o, {
64
- title: F("devportal.appDetails", "App Details"),
65
- description: F("devportal.failedToLoad", "Failed to load"),
62
+ }) : G || !Z ? /* @__PURE__ */ v(o, {
63
+ title: P("devportal.appDetails", "App Details"),
64
+ description: P("devportal.failedToLoad", "Failed to load"),
66
65
  backLink: "/oauth",
67
- backLabel: F("devportal.backToApps", "Back to Apps"),
68
- children: /* @__PURE__ */ b("div", {
66
+ backLabel: P("devportal.backToApps", "Back to Apps"),
67
+ children: /* @__PURE__ */ y("div", {
69
68
  className: "rounded-lg border border-status-error-border/50 bg-status-error-bg/10 p-6 text-center",
70
69
  children: [
71
- /* @__PURE__ */ y(u, { className: "mx-auto h-8 w-8 text-status-error-text" }),
72
- /* @__PURE__ */ y("h3", {
70
+ /* @__PURE__ */ v(ie, { className: "mx-auto h-8 w-8 text-status-error-text" }),
71
+ /* @__PURE__ */ v("h3", {
73
72
  className: "mt-2 font-medium text-status-error-text",
74
- children: K ? F("devportal.failedToLoadApp", "Failed to load app") : F("devportal.appNotFound", "App not found")
73
+ children: G ? P("devportal.failedToLoadApp", "Failed to load app") : P("devportal.appNotFound", "App not found")
75
74
  }),
76
- K && /* @__PURE__ */ y("p", {
75
+ G && /* @__PURE__ */ v("p", {
77
76
  className: "mt-1 text-sm text-text-secondary",
78
- children: a(K)
77
+ children: ee(G)
79
78
  }),
80
- /* @__PURE__ */ b("button", {
81
- onClick: () => Z("/oauth"),
79
+ /* @__PURE__ */ y("button", {
80
+ onClick: () => Q("/oauth"),
82
81
  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",
83
- children: [/* @__PURE__ */ y(d, { size: 16 }), F("devportal.backToApps", "Back to Apps")]
82
+ children: [/* @__PURE__ */ v(ae, { size: 16 }), P("devportal.backToApps", "Back to Apps")]
84
83
  })
85
84
  ]
86
85
  })
87
- }) : /* @__PURE__ */ y(ae, {
88
- permission: s.APP_READ,
89
- children: /* @__PURE__ */ b(o, {
90
- title: X.name,
91
- description: X.description || F("devportal.oauthAppDetailsAndCredentials", "OAuth App details and credentials"),
92
- purpose: F("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."),
86
+ }) : /* @__PURE__ */ v(ne, {
87
+ authOnly: !0,
88
+ children: /* @__PURE__ */ y(o, {
89
+ title: Z.name,
90
+ description: Z.description || P("devportal.oauthAppDetailsAndCredentials", "OAuth App details and credentials"),
91
+ 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."),
93
92
  backLink: "/oauth",
94
- backLabel: F("devportal.backToApps", "Back to Apps"),
95
- actions: /* @__PURE__ */ y(k, {
93
+ backLabel: P("devportal.backToApps", "Back to Apps"),
94
+ actions: /* @__PURE__ */ v(O, {
96
95
  primary: {
97
- label: X.status === "ACTIVE" ? F("devportal.deactivate", "Deactivate") : F("devportal.activate", "Activate"),
96
+ label: Z.status === "ACTIVE" ? P("devportal.deactivate", "Deactivate") : P("devportal.activate", "Activate"),
98
97
  onSelect: async () => {
99
- if (!j || !X) return;
100
- let e = X.status === "ACTIVE" ? "INACTIVE" : "ACTIVE";
98
+ if (!A || !Z) return;
99
+ let e = Z.status === "ACTIVE" ? "INACTIVE" : "ACTIVE";
101
100
  try {
102
- await ce({ variables: {
103
- id: j,
101
+ await oe({ variables: {
102
+ id: A,
104
103
  input: { status: e }
105
- } }), q();
104
+ } }), K();
106
105
  } catch {}
107
106
  }
108
107
  },
109
108
  actions: [{
110
- label: F("devportal.delete", "Delete"),
111
- icon: /* @__PURE__ */ y(_, { size: 16 }),
109
+ label: P("devportal.delete", "Delete"),
110
+ icon: /* @__PURE__ */ v(g, { size: 16 }),
112
111
  intent: "destructive",
113
- onSelect: () => V(!0)
112
+ onSelect: () => B(!0)
114
113
  }]
115
114
  }),
116
115
  children: [
117
- /* @__PURE__ */ b("div", {
116
+ /* @__PURE__ */ y("div", {
118
117
  className: "grid gap-6 md:grid-cols-2",
119
- children: [/* @__PURE__ */ b("div", {
118
+ children: [/* @__PURE__ */ y("div", {
120
119
  className: "rounded-card border border-border-seam bg-bg-surface p-6",
121
- children: [/* @__PURE__ */ y("h3", {
120
+ children: [/* @__PURE__ */ v("h3", {
122
121
  className: "text-sm font-medium text-text-secondary mb-4",
123
- children: F("devportal.statusAndConfiguration", "Status & Configuration")
124
- }), /* @__PURE__ */ b("div", {
122
+ children: P("devportal.statusAndConfiguration", "Status & Configuration")
123
+ }), /* @__PURE__ */ y("div", {
125
124
  className: "space-y-3",
126
125
  children: [
127
- /* @__PURE__ */ b("div", {
126
+ /* @__PURE__ */ y("div", {
128
127
  className: "flex justify-between",
129
- children: [/* @__PURE__ */ y("span", {
128
+ children: [/* @__PURE__ */ v("span", {
130
129
  className: "text-sm text-text-secondary",
131
- children: F("devportal.status", "Status")
132
- }), /* @__PURE__ */ b("div", {
130
+ children: P("devportal.status", "Status")
131
+ }), /* @__PURE__ */ y("div", {
133
132
  className: "flex items-center gap-2",
134
- children: [/* @__PURE__ */ y(te, { active: X.status === "ACTIVE" }), /* @__PURE__ */ y("span", {
133
+ children: [/* @__PURE__ */ v(te, { active: Z.status === "ACTIVE" }), /* @__PURE__ */ v("span", {
135
134
  className: "text-sm font-medium",
136
- children: X.status
135
+ children: Z.status
137
136
  })]
138
137
  })]
139
138
  }),
140
- /* @__PURE__ */ b("div", {
139
+ /* @__PURE__ */ y("div", {
141
140
  className: "flex justify-between",
142
- children: [/* @__PURE__ */ y("span", {
141
+ children: [/* @__PURE__ */ v("span", {
143
142
  className: "text-sm text-text-secondary",
144
- children: F("devportal.type", "Type")
145
- }), /* @__PURE__ */ y("span", {
146
- className: t("rounded px-2 py-0.5 text-xs font-medium", X.type === "SERVICE" ? "bg-accent-purple-subtle text-accent-purple" : X.type === "INTEGRATION" || X.type === "API_INTEGRATION" ? "bg-status-info-bg-subtle text-status-info-text" : "bg-status-success-bg-subtle text-status-success-text"),
147
- children: X.type
143
+ children: P("devportal.type", "Type")
144
+ }), /* @__PURE__ */ v("span", {
145
+ className: t("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"),
146
+ children: Z.type
148
147
  })]
149
148
  }),
150
- /* @__PURE__ */ b("div", {
149
+ /* @__PURE__ */ y("div", {
151
150
  className: "flex justify-between",
152
- children: [/* @__PURE__ */ y("span", {
151
+ children: [/* @__PURE__ */ v("span", {
153
152
  className: "text-sm text-text-secondary",
154
- children: F("devportal.created", "Created")
155
- }), /* @__PURE__ */ y("span", {
153
+ children: P("devportal.created", "Created")
154
+ }), /* @__PURE__ */ v("span", {
156
155
  className: "text-sm",
157
- children: new Date(X.createdAt).toLocaleDateString()
156
+ children: new Date(Z.createdAt).toLocaleDateString()
158
157
  })]
159
158
  })
160
159
  ]
161
160
  })]
162
- }), /* @__PURE__ */ b(A, {
161
+ }), /* @__PURE__ */ y(k, {
163
162
  treatment: "glass",
164
163
  glow: !0,
165
164
  className: "p-6",
166
- children: [/* @__PURE__ */ y("h3", {
165
+ children: [/* @__PURE__ */ v("h3", {
167
166
  className: "text-sm font-medium text-text-secondary mb-4",
168
- children: F("devportal.credentials", "Credentials")
169
- }), /* @__PURE__ */ b("div", {
167
+ children: P("devportal.credentials", "Credentials")
168
+ }), /* @__PURE__ */ y("div", {
170
169
  className: "space-y-3",
171
170
  children: [
172
- /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("label", {
171
+ /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
173
172
  className: "text-xs text-text-secondary",
174
- children: F("devportal.clientId", "Client ID")
175
- }), /* @__PURE__ */ b("div", {
173
+ children: P("devportal.clientId", "Client ID")
174
+ }), /* @__PURE__ */ y("div", {
176
175
  className: "mt-1 flex items-center gap-2",
177
- children: [/* @__PURE__ */ y("code", {
176
+ children: [/* @__PURE__ */ v("code", {
178
177
  className: "flex-1 rounded bg-bg-sunken px-3 py-1.5 text-sm font-mono",
179
- children: X.clientId
180
- }), /* @__PURE__ */ y("button", {
181
- onClick: () => Q(X.clientId),
178
+ children: Z.clientId
179
+ }), /* @__PURE__ */ v("button", {
180
+ onClick: () => $(Z.clientId),
182
181
  className: "rounded p-1.5 hover:bg-bg-sunken transition-colors",
183
182
  title: "Copy",
184
- children: /* @__PURE__ */ y(f, { size: 14 })
183
+ children: /* @__PURE__ */ v(d, { size: 14 })
185
184
  })]
186
185
  })] }),
187
- R && /* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("label", {
186
+ L && /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
188
187
  className: "text-xs text-status-error-text font-medium",
189
- children: F("devportal.newClientSecretShownOnce", "New Client Secret (shown only once!)")
190
- }), /* @__PURE__ */ b("div", {
188
+ children: P("devportal.newClientSecretShownOnce", "New Client Secret (shown only once!)")
189
+ }), /* @__PURE__ */ y("div", {
191
190
  className: "mt-1 flex items-center gap-2",
192
191
  children: [
193
- /* @__PURE__ */ y("code", {
192
+ /* @__PURE__ */ v("code", {
194
193
  className: "flex-1 rounded bg-status-error-bg/10 border border-status-error-border/30 px-3 py-1.5 text-sm font-mono",
195
- children: I ? R : "••••••••••••••••"
194
+ children: F ? L : "••••••••••••••••"
196
195
  }),
197
- /* @__PURE__ */ y("button", {
198
- onClick: () => L(!I),
196
+ /* @__PURE__ */ v("button", {
197
+ onClick: () => I(!F),
199
198
  className: "rounded p-1.5 hover:bg-bg-sunken transition-colors",
200
- children: y(I ? m : p, { size: 14 })
199
+ children: v(F ? p : f, { size: 14 })
201
200
  }),
202
- /* @__PURE__ */ y("button", {
203
- onClick: () => Q(R),
201
+ /* @__PURE__ */ v("button", {
202
+ onClick: () => $(L),
204
203
  className: "rounded p-1.5 hover:bg-bg-sunken transition-colors",
205
- children: /* @__PURE__ */ y(f, { size: 14 })
204
+ children: /* @__PURE__ */ v(d, { size: 14 })
206
205
  })
207
206
  ]
208
207
  })] }),
209
- /* @__PURE__ */ b("button", {
210
- onClick: () => U(!0),
208
+ /* @__PURE__ */ y("button", {
209
+ onClick: () => H(!0),
211
210
  disabled: J,
212
211
  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",
213
- children: [/* @__PURE__ */ y(g, {
212
+ children: [/* @__PURE__ */ v(h, {
214
213
  size: 14,
215
214
  className: J ? "animate-spin" : ""
216
- }), F("devportal.rotateSecret", "Rotate Secret")]
215
+ }), P("devportal.rotateSecret", "Rotate Secret")]
217
216
  })
218
217
  ]
219
218
  })]
220
219
  })]
221
220
  }),
222
- /* @__PURE__ */ b("div", {
221
+ /* @__PURE__ */ y("div", {
223
222
  className: "rounded-card border border-border-seam bg-bg-surface p-6",
224
- children: [/* @__PURE__ */ b("h3", {
223
+ children: [/* @__PURE__ */ y("h3", {
225
224
  className: "text-sm font-medium text-text-secondary mb-3",
226
225
  children: [
227
- F("devportal.scopes", "Scopes"),
226
+ P("devportal.scopes", "Scopes"),
228
227
  " (",
229
- X.scopes.length,
228
+ Z.scopes.length,
230
229
  ")"
231
230
  ]
232
- }), X.scopes.length > 0 ? /* @__PURE__ */ y("div", {
231
+ }), Z.scopes.length > 0 ? /* @__PURE__ */ v("div", {
233
232
  className: "flex flex-wrap gap-2",
234
- children: X.scopes.map((e) => /* @__PURE__ */ y("span", {
233
+ children: Z.scopes.map((e) => /* @__PURE__ */ v("span", {
235
234
  className: "rounded-full bg-action-primary-bg/10 px-3 py-1 text-xs font-medium text-primary",
236
235
  children: e
237
236
  }, e))
238
- }) : /* @__PURE__ */ y("p", {
237
+ }) : /* @__PURE__ */ v("p", {
239
238
  className: "text-sm text-text-secondary",
240
- children: F("devportal.noScopesConfigured", "No scopes configured")
239
+ children: P("devportal.noScopesConfigured", "No scopes configured")
241
240
  })]
242
241
  }),
243
- /* @__PURE__ */ b("div", {
242
+ /* @__PURE__ */ y("div", {
244
243
  className: "rounded-card border border-border-seam bg-bg-surface p-6",
245
- children: [/* @__PURE__ */ b("h3", {
244
+ children: [/* @__PURE__ */ y("h3", {
246
245
  className: "text-sm font-medium text-text-secondary mb-3",
247
246
  children: [
248
- F("devportal.redirectUris", "Redirect URIs"),
247
+ P("devportal.redirectUris", "Redirect URIs"),
249
248
  " (",
250
- X.redirectUris.length,
249
+ Z.redirectUris.length,
251
250
  ")"
252
251
  ]
253
- }), X.redirectUris.length > 0 ? /* @__PURE__ */ y("div", {
252
+ }), Z.redirectUris.length > 0 ? /* @__PURE__ */ v("div", {
254
253
  className: "space-y-2",
255
- children: X.redirectUris.map((e) => /* @__PURE__ */ b("div", {
254
+ children: Z.redirectUris.map((e) => /* @__PURE__ */ y("div", {
256
255
  className: "flex items-center gap-2",
257
- children: [/* @__PURE__ */ y("code", {
256
+ children: [/* @__PURE__ */ v("code", {
258
257
  className: "rounded bg-bg-sunken px-3 py-1.5 text-sm font-mono",
259
258
  children: e
260
- }), /* @__PURE__ */ y("button", {
261
- onClick: () => Q(e),
259
+ }), /* @__PURE__ */ v("button", {
260
+ onClick: () => $(e),
262
261
  className: "rounded p-1 hover:bg-bg-sunken transition-colors",
263
- children: /* @__PURE__ */ y(f, { size: 12 })
262
+ children: /* @__PURE__ */ v(d, { size: 12 })
264
263
  })]
265
264
  }, e))
266
- }) : /* @__PURE__ */ y("p", {
265
+ }) : /* @__PURE__ */ v("p", {
267
266
  className: "text-sm text-text-secondary",
268
- children: F("devportal.noRedirectUrisConfigured", "No redirect URIs configured")
267
+ children: P("devportal.noRedirectUrisConfigured", "No redirect URIs configured")
269
268
  })]
270
269
  }),
271
- /* @__PURE__ */ y(x, {
272
- open: H,
273
- onOpenChange: U,
274
- children: /* @__PURE__ */ b(w, { children: [/* @__PURE__ */ b(D, { children: [/* @__PURE__ */ y(O, { children: F("devportal.rotateClientSecretQuestion", "Rotate Client Secret?") }), /* @__PURE__ */ y(T, { children: F("devportal.rotateSecretWarning", "This will invalidate the current client secret. All integrations using the old secret will stop working immediately.") })] }), /* @__PURE__ */ b(E, { children: [/* @__PURE__ */ y(C, {
270
+ /* @__PURE__ */ v(b, {
271
+ open: V,
272
+ onOpenChange: H,
273
+ 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, {
275
274
  disabled: J,
276
- children: F("devportal.cancel", "Cancel")
277
- }), /* @__PURE__ */ y(S, {
275
+ children: P("devportal.cancel", "Cancel")
276
+ }), /* @__PURE__ */ v(x, {
278
277
  onClick: (e) => {
279
- e.preventDefault(), le();
278
+ e.preventDefault(), se();
280
279
  },
281
280
  disabled: J,
282
281
  className: "bg-status-warning-bg text-white hover:bg-status-warning-bg/90",
283
- children: J ? F("devportal.rotating", "Rotating...") : F("devportal.rotateSecret", "Rotate Secret")
282
+ children: J ? P("devportal.rotating", "Rotating...") : P("devportal.rotateSecret", "Rotate Secret")
284
283
  })] })] })
285
284
  }),
286
- /* @__PURE__ */ y(x, {
287
- open: B,
288
- onOpenChange: V,
289
- children: /* @__PURE__ */ b(w, { children: [/* @__PURE__ */ b(D, { children: [/* @__PURE__ */ y(O, {
285
+ /* @__PURE__ */ v(b, {
286
+ open: z,
287
+ onOpenChange: B,
288
+ children: /* @__PURE__ */ y(C, { children: [/* @__PURE__ */ y(E, { children: [/* @__PURE__ */ v(D, {
290
289
  className: "text-status-error-text",
291
- children: F("devportal.deactivateAppQuestion", "Deactivate App?")
292
- }), /* @__PURE__ */ y(T, { children: F("devportal.deactivateAppWarning", "This will deactivate the app and revoke all tokens. This action cannot be undone easily.") })] }), /* @__PURE__ */ b(E, { children: [/* @__PURE__ */ y(C, {
293
- disabled: Y,
294
- children: F("devportal.cancel", "Cancel")
295
- }), /* @__PURE__ */ y(S, {
290
+ children: P("devportal.deactivateAppQuestion", "Deactivate App?")
291
+ }), /* @__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, {
292
+ disabled: X,
293
+ children: P("devportal.cancel", "Cancel")
294
+ }), /* @__PURE__ */ v(x, {
296
295
  onClick: (e) => {
297
- e.preventDefault(), $();
296
+ e.preventDefault(), ce();
298
297
  },
299
- disabled: Y,
298
+ disabled: X,
300
299
  className: "bg-status-error-bg text-status-error-text hover:bg-status-error-bg/90",
301
- children: Y ? F("devportal.deactivating", "Deactivating...") : F("devportal.deactivate", "Deactivate")
300
+ children: X ? P("devportal.deactivating", "Deactivating...") : P("devportal.deactivate", "Deactivate")
302
301
  })] })] })
303
302
  })
304
303
  ]
@@ -306,6 +305,6 @@ var j = () => {
306
305
  });
307
306
  };
308
307
  //#endregion
309
- export { j as OAuthClientDetailPage };
308
+ export { A as OAuthClientDetailPage };
310
309
 
311
310
  //# sourceMappingURL=OAuthClientDetailPage.js.map