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