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