@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":"OAuthClientDetailPage.js","names":["OAuthClientDetailPage","appId","useParams","useDevportal","useI18n","tr","value","t","key","fallback","showSecret","setShowSecret","useState","newSecret","setNewSecret","confirmDelete","setConfirmDelete","confirmRotate","setConfirmRotate","useGetAuthAppQuery","rotateSecret","rotating","useRotateAppSecretMutation","deactivateApp","deactivating","useDeactivateAppMutation","updateApp","useUpdateAuthAppMutation","app","data","handleNavigate","basePath","path","handleCopy","ok","nativeCopyText","text","handleRotateSecret","secret","refetch","handleDeactivate","loading","PageLayout","Loader2","error","AlertCircle","getErrorMessage","ArrowLeft","PermissionGuard","CTAOverflowMenu","newStatus","Trash2","ActiveIndicator","cn","GlassCard","Copy","jsx","EyeOff","Eye","RefreshCw","scope","uri","AlertDialog","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction"],"sources":["../../../src/devportal/pages/OAuthClientDetailPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useState } from \"react\";\nimport {\n Copy,\n Eye,\n EyeOff,\n Loader2,\n AlertCircle,\n RefreshCw,\n Trash2,\n ArrowLeft,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n CTAOverflowMenu,\n GlassCard,\n} from \"@burdenoff/fe-libs/ui\";\nimport { useParams } from \"react-router\";\nimport { PageLayout } from \"../components/PageLayout\";\nimport { ActiveIndicator } from \"../components/StatusBadge\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport type { AuthApp } from \"../types\";\nimport { cn } from \"../utils/cn\";\nimport {\n nativeCopyText,\n nativeImpact,\n nativeNotify,\n} from \"../../utils/nativeBridge\";\nimport {\n useGetAuthAppQuery,\n useRotateAppSecretMutation,\n useDeactivateAppMutation,\n useUpdateAuthAppMutation,\n getErrorMessage,\n} from \"../hooks\";\n\n/**\n * OAuth App Detail page\n *\n * Shows details for an auth-svc App (replaces devportal-svc OAuthClient detail).\n * Supports secret rotation, deactivation, and status toggle.\n */\nexport const OAuthClientDetailPage: FC = () => {\n const { clientId: appId } = useParams<{ clientId: 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 [showSecret, setShowSecret] = useState(false);\n const [newSecret, setNewSecret] = useState<string | null>(null);\n const [confirmDelete, setConfirmDelete] = useState(false);\n const [confirmRotate, setConfirmRotate] = useState(false);\n\n const { data, loading, error, refetch } = useGetAuthAppQuery({\n variables: { id: appId || \"\" },\n skip: !appId,\n fetchPolicy: \"cache-and-network\",\n });\n\n const [rotateSecret, { loading: rotating }] = useRotateAppSecretMutation();\n const [deactivateApp, { loading: deactivating }] = useDeactivateAppMutation();\n const [updateApp] = useUpdateAuthAppMutation();\n\n const app: AuthApp | null = data?.app\n ? {\n id: data.app.id,\n name: data.app.name,\n description: data.app.description ?? undefined,\n clientId: data.app.clientId,\n type: data.app.type as AuthApp[\"type\"],\n status: data.app.status as AuthApp[\"status\"],\n scopes: data.app.scopes ?? [],\n redirectUris: data.app.redirectUris ?? [],\n ownerUserId: data.app.ownerUserId,\n tenantId: data.app.tenantId,\n createdAt: data.app.createdAt,\n updatedAt: data.app.updatedAt,\n }\n : null;\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n const handleCopy = async (text: string) => {\n void nativeImpact(\"light\");\n const ok = await nativeCopyText(text);\n void nativeNotify(ok ? \"success\" : \"error\");\n };\n\n const handleRotateSecret = async () => {\n if (!appId) return;\n try {\n const result = await rotateSecret({ variables: { id: appId } });\n const secret = result.data?.rotateAppSecret?.clientSecret;\n if (secret) {\n setNewSecret(secret);\n setShowSecret(true);\n }\n setConfirmRotate(false);\n refetch();\n } catch {\n // error handled by Apollo\n }\n };\n\n const handleDeactivate = async () => {\n if (!appId) return;\n try {\n await deactivateApp({ variables: { id: appId } });\n setConfirmDelete(false);\n handleNavigate(\"/oauth\");\n } catch {\n // error handled by Apollo\n }\n };\n\n const handleToggleStatus = async () => {\n if (!appId || !app) return;\n const newStatus = app.status === \"ACTIVE\" ? \"INACTIVE\" : \"ACTIVE\";\n try {\n await updateApp({\n variables: { id: appId, input: { status: newStatus } },\n });\n refetch();\n } catch {\n // error handled by Apollo\n }\n };\n\n if (loading && !data) {\n return (\n <PageLayout\n title={tr(\"devportal.appDetails\", \"App Details\")}\n description={tr(\"devportal.loadingDots\", \"Loading...\")}\n backLink=\"/oauth\"\n backLabel={tr(\"devportal.backToApps\", \"Back to Apps\")}\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.appDetails\", \"App Details\")}\n description={tr(\"devportal.failedToLoad\", \"Failed to load\")}\n backLink=\"/oauth\"\n backLabel={tr(\"devportal.backToApps\", \"Back to Apps\")}\n >\n <div className=\"rounded-lg border border-status-error-border/50 bg-status-error-bg/10 p-6 text-center\">\n <AlertCircle className=\"mx-auto h-8 w-8 text-status-error-text\" />\n <h3 className=\"mt-2 font-medium text-status-error-text\">\n {error\n ? tr(\"devportal.failedToLoadApp\", \"Failed to load app\")\n : tr(\"devportal.appNotFound\", \"App not found\")}\n </h3>\n {error && (\n <p className=\"mt-1 text-sm text-text-secondary\">\n {getErrorMessage(error)}\n </p>\n )}\n <button\n onClick={() => handleNavigate(\"/oauth\")}\n 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\"\n >\n <ArrowLeft size={16} />\n {tr(\"devportal.backToApps\", \"Back to Apps\")}\n </button>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={app.name}\n description={\n app.description ||\n tr(\n \"devportal.oauthAppDetailsAndCredentials\",\n \"OAuth App details and credentials\",\n )\n }\n purpose={tr(\n \"devportal.oauthAppDetailPurpose\",\n \"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.\",\n )}\n backLink=\"/oauth\"\n backLabel={tr(\"devportal.backToApps\", \"Back to Apps\")}\n actions={\n <CTAOverflowMenu\n primary={{\n label:\n app.status === \"ACTIVE\"\n ? tr(\"devportal.deactivate\", \"Deactivate\")\n : tr(\"devportal.activate\", \"Activate\"),\n onSelect: handleToggleStatus,\n }}\n actions={[\n {\n label: tr(\"devportal.delete\", \"Delete\"),\n icon: <Trash2 size={16} />,\n intent: \"destructive\",\n onSelect: () => setConfirmDelete(true),\n },\n ]}\n />\n }\n >\n {/* Status & Type */}\n <div className=\"grid gap-6 md:grid-cols-2\">\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-6\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-4\">\n {tr(\"devportal.statusAndConfiguration\", \"Status & Configuration\")}\n </h3>\n <div className=\"space-y-3\">\n <div className=\"flex justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {tr(\"devportal.status\", \"Status\")}\n </span>\n <div className=\"flex items-center gap-2\">\n <ActiveIndicator active={app.status === \"ACTIVE\"} />\n <span className=\"text-sm font-medium\">{app.status}</span>\n </div>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {tr(\"devportal.type\", \"Type\")}\n </span>\n <span\n className={cn(\n \"rounded px-2 py-0.5 text-xs font-medium\",\n app.type === \"SERVICE\"\n ? \"bg-accent-purple-subtle text-accent-purple\"\n : app.type === \"INTEGRATION\" ||\n app.type === \"API_INTEGRATION\"\n ? \"bg-status-info-bg-subtle text-status-info-text\"\n : \"bg-status-success-bg-subtle text-status-success-text\",\n )}\n >\n {app.type}\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {tr(\"devportal.created\", \"Created\")}\n </span>\n <span className=\"text-sm\">\n {new Date(app.createdAt).toLocaleDateString()}\n </span>\n </div>\n </div>\n </div>\n\n {/* Credentials — primary emphasis zone */}\n <GlassCard treatment=\"glass\" glow className=\"p-6\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-4\">\n {tr(\"devportal.credentials\", \"Credentials\")}\n </h3>\n <div className=\"space-y-3\">\n <div>\n <label className=\"text-xs text-text-secondary\">\n {tr(\"devportal.clientId\", \"Client ID\")}\n </label>\n <div className=\"mt-1 flex items-center gap-2\">\n <code className=\"flex-1 rounded bg-bg-sunken px-3 py-1.5 text-sm font-mono\">\n {app.clientId}\n </code>\n <button\n onClick={() => handleCopy(app.clientId)}\n className=\"rounded p-1.5 hover:bg-bg-sunken transition-colors\"\n title=\"Copy\"\n >\n <Copy size={14} />\n </button>\n </div>\n </div>\n {newSecret && (\n <div>\n <label className=\"text-xs text-status-error-text font-medium\">\n {tr(\n \"devportal.newClientSecretShownOnce\",\n \"New Client Secret (shown only once!)\",\n )}\n </label>\n <div className=\"mt-1 flex items-center gap-2\">\n <code className=\"flex-1 rounded bg-status-error-bg/10 border border-status-error-border/30 px-3 py-1.5 text-sm font-mono\">\n {showSecret\n ? newSecret\n : \"\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\"}\n </code>\n <button\n onClick={() => setShowSecret(!showSecret)}\n className=\"rounded p-1.5 hover:bg-bg-sunken transition-colors\"\n >\n {showSecret ? <EyeOff size={14} /> : <Eye size={14} />}\n </button>\n <button\n onClick={() => handleCopy(newSecret)}\n className=\"rounded p-1.5 hover:bg-bg-sunken transition-colors\"\n >\n <Copy size={14} />\n </button>\n </div>\n </div>\n )}\n <button\n onClick={() => setConfirmRotate(true)}\n disabled={rotating}\n 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\"\n >\n <RefreshCw\n size={14}\n className={rotating ? \"animate-spin\" : \"\"}\n />\n {tr(\"devportal.rotateSecret\", \"Rotate Secret\")}\n </button>\n </div>\n </GlassCard>\n </div>\n\n {/* Scopes */}\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-6\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-3\">\n {tr(\"devportal.scopes\", \"Scopes\")} ({app.scopes.length})\n </h3>\n {app.scopes.length > 0 ? (\n <div className=\"flex flex-wrap gap-2\">\n {app.scopes.map((scope) => (\n <span\n key={scope}\n className=\"rounded-full bg-action-primary-bg/10 px-3 py-1 text-xs font-medium text-primary\"\n >\n {scope}\n </span>\n ))}\n </div>\n ) : (\n <p className=\"text-sm text-text-secondary\">\n {tr(\"devportal.noScopesConfigured\", \"No scopes configured\")}\n </p>\n )}\n </div>\n\n {/* Redirect URIs */}\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-6\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-3\">\n {tr(\"devportal.redirectUris\", \"Redirect URIs\")} (\n {app.redirectUris.length})\n </h3>\n {app.redirectUris.length > 0 ? (\n <div className=\"space-y-2\">\n {app.redirectUris.map((uri) => (\n <div key={uri} className=\"flex items-center gap-2\">\n <code className=\"rounded bg-bg-sunken px-3 py-1.5 text-sm font-mono\">\n {uri}\n </code>\n <button\n onClick={() => handleCopy(uri)}\n className=\"rounded p-1 hover:bg-bg-sunken transition-colors\"\n >\n <Copy size={12} />\n </button>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-sm text-text-secondary\">\n {tr(\n \"devportal.noRedirectUrisConfigured\",\n \"No redirect URIs configured\",\n )}\n </p>\n )}\n </div>\n\n {/* Confirm Rotate Dialog */}\n <AlertDialog open={confirmRotate} onOpenChange={setConfirmRotate}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>\n {tr(\n \"devportal.rotateClientSecretQuestion\",\n \"Rotate Client Secret?\",\n )}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {tr(\n \"devportal.rotateSecretWarning\",\n \"This will invalidate the current client secret. All integrations using the old secret will stop working immediately.\",\n )}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={rotating}>\n {tr(\"devportal.cancel\", \"Cancel\")}\n </AlertDialogCancel>\n <AlertDialogAction\n onClick={(e) => {\n e.preventDefault();\n void handleRotateSecret();\n }}\n disabled={rotating}\n className=\"bg-status-warning-bg text-white hover:bg-status-warning-bg/90\"\n >\n {rotating\n ? tr(\"devportal.rotating\", \"Rotating...\")\n : tr(\"devportal.rotateSecret\", \"Rotate Secret\")}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n\n {/* Confirm Deactivate Dialog */}\n <AlertDialog open={confirmDelete} onOpenChange={setConfirmDelete}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle className=\"text-status-error-text\">\n {tr(\"devportal.deactivateAppQuestion\", \"Deactivate App?\")}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {tr(\n \"devportal.deactivateAppWarning\",\n \"This will deactivate the app and revoke all tokens. This action cannot be undone easily.\",\n )}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={deactivating}>\n {tr(\"devportal.cancel\", \"Cancel\")}\n </AlertDialogCancel>\n <AlertDialogAction\n onClick={(e) => {\n e.preventDefault();\n void handleDeactivate();\n }}\n disabled={deactivating}\n className=\"bg-status-error-bg text-status-error-text hover:bg-status-error-bg/90\"\n >\n {deactivating\n ? tr(\"devportal.deactivating\", \"Deactivating...\")\n : tr(\"devportal.deactivate\", \"Deactivate\")}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"OAuthClientDetailPage.js","names":["OAuthClientDetailPage","appId","useParams","useDevportal","useI18n","tr","value","t","key","fallback","showSecret","setShowSecret","useState","newSecret","setNewSecret","confirmDelete","setConfirmDelete","confirmRotate","setConfirmRotate","actionError","setActionError","isFluidgrids","useIsFluidgridsVariant","useGetAuthAppQuery","rotateSecret","rotating","useRotateAppSecretMutation","deactivateApp","deactivating","useDeactivateAppMutation","updateApp","useUpdateAuthAppMutation","app","data","handleNavigate","basePath","path","handleCopy","ok","nativeCopyText","text","handleRotateSecret","secret","refetch","err","errorMessage","handleDeactivate","loading","PageLayout","Loader2","error","AlertCircle","getErrorMessage","ArrowLeft","PermissionGuard","CTAOverflowMenu","newStatus","Trash2","ActiveIndicator","cn","GlassCard","Copy","jsx","EyeOff","Eye","RefreshCw","scope","uri","AlertDialog","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction"],"sources":["../../../src/devportal/pages/OAuthClientDetailPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useState } from \"react\";\nimport {\n Copy,\n Eye,\n EyeOff,\n Loader2,\n AlertCircle,\n RefreshCw,\n Trash2,\n ArrowLeft,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n CTAOverflowMenu,\n GlassCard,\n} from \"@burdenoff/fe-libs/ui\";\nimport { useParams } from \"react-router\";\nimport { PageLayout } from \"../components/PageLayout\";\nimport { ActiveIndicator } from \"../components/StatusBadge\";\nimport {\n useDevportal,\n useIsFluidgridsVariant,\n} from \"../providers/DevportalProvider\";\nimport { errorMessage } from \"../utils/errorMessage\";\nimport { PermissionGuard } from \"../components\";\nimport type { AuthApp } from \"../types\";\nimport { cn } from \"../utils/cn\";\nimport {\n nativeCopyText,\n nativeImpact,\n nativeNotify,\n} from \"../../utils/nativeBridge\";\nimport {\n useGetAuthAppQuery,\n useRotateAppSecretMutation,\n useDeactivateAppMutation,\n useUpdateAuthAppMutation,\n getErrorMessage,\n} from \"../hooks\";\n\n/**\n * OAuth App Detail page\n *\n * Shows details for an auth-svc App (replaces devportal-svc OAuthClient detail).\n * Supports secret rotation, deactivation, and status toggle.\n */\nexport const OAuthClientDetailPage: FC = () => {\n const { clientId: appId } = useParams<{ clientId: 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 [showSecret, setShowSecret] = useState(false);\n const [newSecret, setNewSecret] = useState<string | null>(null);\n const [confirmDelete, setConfirmDelete] = useState(false);\n const [confirmRotate, setConfirmRotate] = useState(false);\n // A failed rotate / deactivate / status change stays visible (never swallowed).\n const [actionError, setActionError] = useState<string | null>(null);\n // FluidGrids: the \"Delete\" action only deactivates, so it is labelled that way.\n const isFluidgrids = useIsFluidgridsVariant();\n\n const { data, loading, error, refetch } = useGetAuthAppQuery({\n variables: { id: appId || \"\" },\n skip: !appId,\n fetchPolicy: \"cache-and-network\",\n });\n\n const [rotateSecret, { loading: rotating }] = useRotateAppSecretMutation();\n const [deactivateApp, { loading: deactivating }] = useDeactivateAppMutation();\n const [updateApp] = useUpdateAuthAppMutation();\n\n const app: AuthApp | null = data?.app\n ? {\n id: data.app.id,\n name: data.app.name,\n description: data.app.description ?? undefined,\n clientId: data.app.clientId,\n type: data.app.type as AuthApp[\"type\"],\n status: data.app.status as AuthApp[\"status\"],\n scopes: data.app.scopes ?? [],\n redirectUris: data.app.redirectUris ?? [],\n ownerUserId: data.app.ownerUserId,\n tenantId: data.app.tenantId,\n createdAt: data.app.createdAt,\n updatedAt: data.app.updatedAt,\n }\n : null;\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n const handleCopy = async (text: string) => {\n void nativeImpact(\"light\");\n const ok = await nativeCopyText(text);\n void nativeNotify(ok ? \"success\" : \"error\");\n };\n\n const handleRotateSecret = async () => {\n if (!appId) return;\n setActionError(null);\n try {\n const result = await rotateSecret({ variables: { id: appId } });\n const secret = result.data?.rotateAppSecret?.clientSecret;\n if (secret) {\n setNewSecret(secret);\n setShowSecret(true);\n }\n setConfirmRotate(false);\n refetch();\n } catch (err) {\n setActionError(\n errorMessage(\n err,\n tr(\n \"devportal.oauthActionFailed\",\n \"That did not work. Nothing was changed. Please try again.\",\n ),\n ),\n );\n }\n };\n\n const handleDeactivate = async () => {\n if (!appId) return;\n setActionError(null);\n try {\n await deactivateApp({ variables: { id: appId } });\n setConfirmDelete(false);\n handleNavigate(\"/oauth\");\n } catch (err) {\n setActionError(\n errorMessage(\n err,\n tr(\n \"devportal.oauthActionFailed\",\n \"That did not work. Nothing was changed. Please try again.\",\n ),\n ),\n );\n }\n };\n\n const handleToggleStatus = async () => {\n if (!appId || !app) return;\n setActionError(null);\n const newStatus = app.status === \"ACTIVE\" ? \"INACTIVE\" : \"ACTIVE\";\n try {\n await updateApp({\n variables: { id: appId, input: { status: newStatus } },\n });\n refetch();\n } catch (err) {\n setActionError(\n errorMessage(\n err,\n tr(\n \"devportal.oauthActionFailed\",\n \"That did not work. Nothing was changed. Please try again.\",\n ),\n ),\n );\n }\n };\n\n if (loading && !data) {\n return (\n <PageLayout\n title={tr(\"devportal.appDetails\", \"App Details\")}\n description={tr(\"devportal.loadingDots\", \"Loading...\")}\n backLink=\"/oauth\"\n backLabel={tr(\"devportal.backToApps\", \"Back to Apps\")}\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.appDetails\", \"App Details\")}\n description={tr(\"devportal.failedToLoad\", \"Failed to load\")}\n backLink=\"/oauth\"\n backLabel={tr(\"devportal.backToApps\", \"Back to Apps\")}\n >\n <div className=\"rounded-lg border border-status-error-border/50 bg-status-error-bg/10 p-6 text-center\">\n <AlertCircle className=\"mx-auto h-8 w-8 text-status-error-text\" />\n <h3 className=\"mt-2 font-medium text-status-error-text\">\n {error\n ? tr(\"devportal.failedToLoadApp\", \"Failed to load app\")\n : tr(\"devportal.appNotFound\", \"App not found\")}\n </h3>\n {error && (\n <p className=\"mt-1 text-sm text-text-secondary\">\n {getErrorMessage(error)}\n </p>\n )}\n <button\n onClick={() => handleNavigate(\"/oauth\")}\n 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\"\n >\n <ArrowLeft size={16} />\n {tr(\"devportal.backToApps\", \"Back to Apps\")}\n </button>\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={app.name}\n description={\n app.description ||\n tr(\n \"devportal.oauthAppDetailsAndCredentials\",\n \"OAuth App details and credentials\",\n )\n }\n purpose={tr(\n \"devportal.oauthAppDetailPurpose\",\n \"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.\",\n )}\n backLink=\"/oauth\"\n backLabel={tr(\"devportal.backToApps\", \"Back to Apps\")}\n actions={\n <CTAOverflowMenu\n primary={{\n label:\n app.status === \"ACTIVE\"\n ? tr(\"devportal.deactivate\", \"Deactivate\")\n : tr(\"devportal.activate\", \"Activate\"),\n onSelect: handleToggleStatus,\n }}\n actions={[\n {\n label: isFluidgrids\n ? tr(\"devportal.deactivate\", \"Deactivate\")\n : tr(\"devportal.delete\", \"Delete\"),\n icon: <Trash2 size={16} />,\n intent: \"destructive\",\n onSelect: () => setConfirmDelete(true),\n },\n ]}\n />\n }\n >\n {actionError && (\n <div\n role=\"alert\"\n className=\"mb-4 rounded-md bg-status-error-bg px-3 py-2 text-sm text-status-error-text\"\n >\n {actionError}\n </div>\n )}\n {/* Status & Type */}\n <div className=\"grid gap-6 md:grid-cols-2\">\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-6\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-4\">\n {tr(\"devportal.statusAndConfiguration\", \"Status & Configuration\")}\n </h3>\n <div className=\"space-y-3\">\n <div className=\"flex justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {tr(\"devportal.status\", \"Status\")}\n </span>\n <div className=\"flex items-center gap-2\">\n <ActiveIndicator active={app.status === \"ACTIVE\"} />\n <span className=\"text-sm font-medium\">{app.status}</span>\n </div>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {tr(\"devportal.type\", \"Type\")}\n </span>\n <span\n className={cn(\n \"rounded px-2 py-0.5 text-xs font-medium\",\n app.type === \"SERVICE\"\n ? \"bg-accent-purple-subtle text-accent-purple\"\n : app.type === \"INTEGRATION\" ||\n app.type === \"API_INTEGRATION\"\n ? \"bg-status-info-bg-subtle text-status-info-text\"\n : \"bg-status-success-bg-subtle text-status-success-text\",\n )}\n >\n {app.type}\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {tr(\"devportal.created\", \"Created\")}\n </span>\n <span className=\"text-sm\">\n {new Date(app.createdAt).toLocaleDateString()}\n </span>\n </div>\n </div>\n </div>\n\n {/* Credentials — primary emphasis zone */}\n <GlassCard treatment=\"glass\" glow className=\"p-6\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-4\">\n {tr(\"devportal.credentials\", \"Credentials\")}\n </h3>\n <div className=\"space-y-3\">\n <div>\n <label className=\"text-xs text-text-secondary\">\n {tr(\"devportal.clientId\", \"Client ID\")}\n </label>\n <div className=\"mt-1 flex items-center gap-2\">\n <code className=\"flex-1 rounded bg-bg-sunken px-3 py-1.5 text-sm font-mono\">\n {app.clientId}\n </code>\n <button\n onClick={() => handleCopy(app.clientId)}\n className=\"rounded p-1.5 hover:bg-bg-sunken transition-colors\"\n title=\"Copy\"\n >\n <Copy size={14} />\n </button>\n </div>\n </div>\n {newSecret && (\n <div>\n <label className=\"text-xs text-status-error-text font-medium\">\n {tr(\n \"devportal.newClientSecretShownOnce\",\n \"New Client Secret (shown only once!)\",\n )}\n </label>\n <div className=\"mt-1 flex items-center gap-2\">\n <code className=\"flex-1 rounded bg-status-error-bg/10 border border-status-error-border/30 px-3 py-1.5 text-sm font-mono\">\n {showSecret\n ? newSecret\n : \"\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\\u2022\"}\n </code>\n <button\n onClick={() => setShowSecret(!showSecret)}\n className=\"rounded p-1.5 hover:bg-bg-sunken transition-colors\"\n >\n {showSecret ? <EyeOff size={14} /> : <Eye size={14} />}\n </button>\n <button\n onClick={() => handleCopy(newSecret)}\n className=\"rounded p-1.5 hover:bg-bg-sunken transition-colors\"\n >\n <Copy size={14} />\n </button>\n </div>\n </div>\n )}\n <button\n onClick={() => setConfirmRotate(true)}\n disabled={rotating}\n 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\"\n >\n <RefreshCw\n size={14}\n className={rotating ? \"animate-spin\" : \"\"}\n />\n {tr(\"devportal.rotateSecret\", \"Rotate Secret\")}\n </button>\n </div>\n </GlassCard>\n </div>\n\n {/* Scopes */}\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-6\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-3\">\n {tr(\"devportal.scopes\", \"Scopes\")} ({app.scopes.length})\n </h3>\n {app.scopes.length > 0 ? (\n <div className=\"flex flex-wrap gap-2\">\n {app.scopes.map((scope) => (\n <span\n key={scope}\n className=\"rounded-full bg-action-primary-bg/10 px-3 py-1 text-xs font-medium text-primary\"\n >\n {scope}\n </span>\n ))}\n </div>\n ) : (\n <p className=\"text-sm text-text-secondary\">\n {tr(\"devportal.noScopesConfigured\", \"No scopes configured\")}\n </p>\n )}\n </div>\n\n {/* Redirect URIs */}\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-6\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-3\">\n {tr(\"devportal.redirectUris\", \"Redirect URIs\")} (\n {app.redirectUris.length})\n </h3>\n {app.redirectUris.length > 0 ? (\n <div className=\"space-y-2\">\n {app.redirectUris.map((uri) => (\n <div key={uri} className=\"flex items-center gap-2\">\n <code className=\"rounded bg-bg-sunken px-3 py-1.5 text-sm font-mono\">\n {uri}\n </code>\n <button\n onClick={() => handleCopy(uri)}\n className=\"rounded p-1 hover:bg-bg-sunken transition-colors\"\n >\n <Copy size={12} />\n </button>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-sm text-text-secondary\">\n {tr(\n \"devportal.noRedirectUrisConfigured\",\n \"No redirect URIs configured\",\n )}\n </p>\n )}\n </div>\n\n {/* Confirm Rotate Dialog */}\n <AlertDialog open={confirmRotate} onOpenChange={setConfirmRotate}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>\n {tr(\n \"devportal.rotateClientSecretQuestion\",\n \"Rotate Client Secret?\",\n )}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {tr(\n \"devportal.rotateSecretWarning\",\n \"This will invalidate the current client secret. All integrations using the old secret will stop working immediately.\",\n )}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={rotating}>\n {tr(\"devportal.cancel\", \"Cancel\")}\n </AlertDialogCancel>\n <AlertDialogAction\n onClick={(e) => {\n e.preventDefault();\n void handleRotateSecret();\n }}\n disabled={rotating}\n className=\"bg-status-warning-bg text-white hover:bg-status-warning-bg/90\"\n >\n {rotating\n ? tr(\"devportal.rotating\", \"Rotating...\")\n : tr(\"devportal.rotateSecret\", \"Rotate Secret\")}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n\n {/* Confirm Deactivate Dialog */}\n <AlertDialog open={confirmDelete} onOpenChange={setConfirmDelete}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle className=\"text-status-error-text\">\n {tr(\"devportal.deactivateAppQuestion\", \"Deactivate App?\")}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {tr(\n \"devportal.deactivateAppWarning\",\n \"This will deactivate the app and revoke all tokens. This action cannot be undone easily.\",\n )}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={deactivating}>\n {tr(\"devportal.cancel\", \"Cancel\")}\n </AlertDialogCancel>\n <AlertDialogAction\n onClick={(e) => {\n e.preventDefault();\n void handleDeactivate();\n }}\n disabled={deactivating}\n className=\"bg-status-error-bg text-status-error-text hover:bg-status-error-bg/90\"\n >\n {deactivating\n ? tr(\"devportal.deactivating\", \"Deactivating...\")\n : tr(\"devportal.deactivate\", \"Deactivate\")}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </PageLayout>\n </PermissionGuard>\n );\n};\n"],"mappings":"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"}
@@ -1,17 +1,18 @@
1
1
  import { PageLayout as e } from "../components/PageLayout.js";
2
2
  import { EmptyState as t } from "../components/EmptyState.js";
3
3
  import { useDevportal as n } from "../providers/DevportalProvider.js";
4
- import { PermissionGuard as r } from "../components/PermissionGuard.js";
5
4
  import "../components/index.js";
5
+ import { PermissionGuard as r } from "../components/PermissionGuard.js";
6
6
  import { formatCurrency as i } from "../utils/currency.js";
7
7
  import { resolveGlobalGraphqlEndpoint as a } from "../utils/graphqlEndpoint.js";
8
- import { useEffect as o, useState as s } from "react";
9
- import { ArrowRight as c, Building2 as l, CheckCircle2 as u, Clock as d, DollarSign as f, Loader2 as p, Package as m, Plus as h } from "lucide-react";
10
- import { Fragment as g, jsx as _, jsxs as v } from "react/jsx-runtime";
11
- import { useI18n as y } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
12
- import { GlassCard as b, GradientText as x } from "@burdenoff/fe-libs/ui";
8
+ import { StoreImage as o } from "../components/StoreImage.js";
9
+ import { useEffect as s, useState as c } from "react";
10
+ import { ArrowRight as l, Building2 as u, CheckCircle2 as d, Clock as f, DollarSign as p, Loader2 as m, Package as h, Plus as g } from "lucide-react";
11
+ import { Fragment as _, jsx as v, jsxs as y } from "react/jsx-runtime";
12
+ import { useI18n as b } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
13
+ import { GlassCard as x, GradientText as S } from "@burdenoff/fe-libs/ui";
13
14
  // src/devportal/pages/SellerDashboardPage.tsx
14
- var S = {
15
+ var C = {
15
16
  PUBLISHED: {
16
17
  label: "Published",
17
18
  className: "text-status-success-text bg-status-success-bg-subtle"
@@ -33,7 +34,7 @@ var S = {
33
34
  className: "text-text-muted bg-bg-muted"
34
35
  }
35
36
  };
36
- function C(e, t) {
37
+ function w(e, t) {
37
38
  let n = t || "USD";
38
39
  return `${new Intl.NumberFormat("en-US", {
39
40
  style: "currency",
@@ -42,26 +43,26 @@ function C(e, t) {
42
43
  maximumFractionDigits: 2
43
44
  }).format(e)} ${n}`;
44
45
  }
45
- var w = "\n query SellerDashboardBootstrap {\n myDeveloperOrganizations {\n id\n name\n slug\n logoUrl\n isVerified\n publishedApps\n totalInstalls\n totalRevenue\n kind\n }\n myPublisher {\n id\n }\n }\n";
46
- function T(e) {
46
+ var T = "\n query SellerDashboardBootstrap {\n myDeveloperOrganizations {\n id\n name\n slug\n logoUrl\n isVerified\n publishedApps\n totalInstalls\n totalRevenue\n kind\n }\n myPublisher {\n id\n }\n }\n";
47
+ function E(e) {
47
48
  return `query SellerDashboardOrgCurrencies {\n ${e.map((e, t) => `o${t}: developerOrgRevenueSummary(organizationId: ${JSON.stringify(e)}, period: "monthly") { currency }`).join("\n ")}\n }`;
48
49
  }
49
- var E = "\n query SellerDashboardProducts($publisherId: String!) {\n products(filter: { publisherId: $publisherId, nature: PHYSICAL }, limit: 3, offset: 0) {\n id\n name\n slug\n type\n status\n price\n currency\n stockQuantity\n icon\n }\n }\n", D = () => {
50
- let { navigate: i, basePath: f, apiGatewayUrl: b, authToken: S } = n(), { t: C } = y(), D = (e, t) => {
50
+ var D = "\n query SellerDashboardProducts($publisherId: String!) {\n products(filter: { publisherId: $publisherId, nature: PHYSICAL }, limit: 3, offset: 0) {\n id\n name\n slug\n type\n status\n price\n currency\n stockQuantity\n icon\n }\n }\n", O = () => {
51
+ let { navigate: i, basePath: o, apiGatewayUrl: p, authToken: x } = n(), { t: C } = b(), w = (e, t) => {
51
52
  let n = C(e);
52
53
  return n === e ? t : n;
53
- }, M = a(b), [N, P] = s(!0), [F, I] = s(!1), [L, R] = s([]), [z, B] = s(null), [V, H] = s([]), [U, W] = s({});
54
- o(() => {
54
+ }, O = a(p), [N, P] = c(!0), [F, I] = c(!1), [L, R] = c([]), [z, B] = c(null), [V, H] = c([]), [U, W] = c({});
55
+ s(() => {
55
56
  let e = !1;
56
57
  return P(!0), (async () => {
57
58
  try {
58
- let t = await fetch(M, {
59
+ let t = await fetch(O, {
59
60
  method: "POST",
60
61
  headers: {
61
62
  "Content-Type": "application/json",
62
- Authorization: `Bearer ${S ?? ""}`
63
+ Authorization: `Bearer ${x ?? ""}`
63
64
  },
64
- body: JSON.stringify({ query: w })
65
+ body: JSON.stringify({ query: T })
65
66
  });
66
67
  if (e) return;
67
68
  let n = await t.json();
@@ -73,19 +74,19 @@ var E = "\n query SellerDashboardProducts($publisherId: String!) {\n product
73
74
  })(), () => {
74
75
  e = !0;
75
76
  };
76
- }, [M, S]), o(() => {
77
+ }, [O, x]), s(() => {
77
78
  if (!z) return;
78
79
  let e = !1;
79
80
  return I(!0), (async () => {
80
81
  try {
81
- let t = await fetch(M, {
82
+ let t = await fetch(O, {
82
83
  method: "POST",
83
84
  headers: {
84
85
  "Content-Type": "application/json",
85
- Authorization: `Bearer ${S ?? ""}`
86
+ Authorization: `Bearer ${x ?? ""}`
86
87
  },
87
88
  body: JSON.stringify({
88
- query: E,
89
+ query: D,
89
90
  variables: { publisherId: z }
90
91
  })
91
92
  });
@@ -109,21 +110,21 @@ var E = "\n query SellerDashboardProducts($publisherId: String!) {\n product
109
110
  };
110
111
  }, [
111
112
  z,
112
- M,
113
- S
114
- ]), o(() => {
113
+ O,
114
+ x
115
+ ]), s(() => {
115
116
  let e = L.slice(0, 3).map((e) => e.id);
116
117
  if (e.length === 0) return;
117
118
  let t = !1;
118
119
  return (async () => {
119
120
  try {
120
- let n = await fetch(M, {
121
+ let n = await fetch(O, {
121
122
  method: "POST",
122
123
  headers: {
123
124
  "Content-Type": "application/json",
124
- Authorization: `Bearer ${S ?? ""}`
125
+ Authorization: `Bearer ${x ?? ""}`
125
126
  },
126
- body: JSON.stringify({ query: T(e) })
127
+ body: JSON.stringify({ query: E(e) })
127
128
  });
128
129
  if (t) return;
129
130
  let r = await n.json();
@@ -139,96 +140,96 @@ var E = "\n query SellerDashboardProducts($publisherId: String!) {\n product
139
140
  };
140
141
  }, [
141
142
  L.map((e) => e.id).join(","),
142
- M,
143
- S
143
+ O,
144
+ x
144
145
  ]);
145
146
  let G = N, K = N || F, q = V.length, J = V.filter((e) => e.status === "PENDING_REVIEW").length, Y = V.filter((e) => e.status === "PUBLISHED").length, X = (e) => {
146
- i?.(`${f}${e}`);
147
+ i?.(`${o}${e}`);
147
148
  };
148
- return /* @__PURE__ */ _(r, {
149
+ return /* @__PURE__ */ v(r, {
149
150
  authOnly: !0,
150
- children: /* @__PURE__ */ _(e, {
151
- title: /* @__PURE__ */ v(g, { children: [
152
- D("devportal.seller", "Seller"),
151
+ children: /* @__PURE__ */ v(e, {
152
+ title: /* @__PURE__ */ y(_, { children: [
153
+ w("devportal.seller", "Seller"),
153
154
  " ",
154
- /* @__PURE__ */ _(x, { children: D("devportal.dashboard", "Dashboard") })
155
+ /* @__PURE__ */ v(S, { children: w("devportal.dashboard", "Dashboard") })
155
156
  ] }),
156
- actions: G ? null : /* @__PURE__ */ v("button", {
157
+ actions: G ? null : /* @__PURE__ */ y("button", {
157
158
  onClick: () => X("/seller/items/new"),
158
159
  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 transition-colors",
159
- children: [/* @__PURE__ */ _(h, { size: 16 }), D("devportal.listAnItem", "List an Item")]
160
+ children: [/* @__PURE__ */ v(g, { size: 16 }), w("devportal.listAnItem", "List an Item")]
160
161
  }),
161
- children: /* @__PURE__ */ v("div", {
162
+ children: /* @__PURE__ */ y("div", {
162
163
  className: "flex flex-col gap-8",
163
164
  children: [
164
- /* @__PURE__ */ _("div", {
165
+ /* @__PURE__ */ v("div", {
165
166
  className: "flex items-center gap-6 border-b border-border-seam pb-6",
166
- children: K ? /* @__PURE__ */ _(p, { className: "h-4 w-4 animate-spin text-text-secondary" }) : /* @__PURE__ */ v(g, { children: [
167
- /* @__PURE__ */ _(O, {
168
- icon: /* @__PURE__ */ _(m, { size: 14 }),
167
+ children: K ? /* @__PURE__ */ v(m, { className: "h-4 w-4 animate-spin text-text-secondary" }) : /* @__PURE__ */ y(_, { children: [
168
+ /* @__PURE__ */ v(k, {
169
+ icon: /* @__PURE__ */ v(h, { size: 14 }),
169
170
  value: q,
170
- label: D("devportal.items", "Items")
171
+ label: w("devportal.items", "Items")
171
172
  }),
172
- /* @__PURE__ */ _("div", { className: "h-4 w-px bg-border-seam" }),
173
- /* @__PURE__ */ _(O, {
174
- icon: /* @__PURE__ */ _(d, { size: 14 }),
173
+ /* @__PURE__ */ v("div", { className: "h-4 w-px bg-border-seam" }),
174
+ /* @__PURE__ */ v(k, {
175
+ icon: /* @__PURE__ */ v(f, { size: 14 }),
175
176
  value: J,
176
- label: D("devportal.pendingReview", "Pending Review")
177
+ label: w("devportal.pendingReview", "Pending Review")
177
178
  }),
178
- /* @__PURE__ */ _("div", { className: "h-4 w-px bg-border-seam" }),
179
- /* @__PURE__ */ _(O, {
180
- icon: /* @__PURE__ */ _(u, { size: 14 }),
179
+ /* @__PURE__ */ v("div", { className: "h-4 w-px bg-border-seam" }),
180
+ /* @__PURE__ */ v(k, {
181
+ icon: /* @__PURE__ */ v(d, { size: 14 }),
181
182
  value: Y,
182
- label: D("devportal.published", "Published")
183
+ label: w("devportal.published", "Published")
183
184
  }),
184
- /* @__PURE__ */ _("div", { className: "h-4 w-px bg-border-seam" }),
185
- /* @__PURE__ */ _(O, {
186
- icon: /* @__PURE__ */ _(l, { size: 14 }),
185
+ /* @__PURE__ */ v("div", { className: "h-4 w-px bg-border-seam" }),
186
+ /* @__PURE__ */ v(k, {
187
+ icon: /* @__PURE__ */ v(u, { size: 14 }),
187
188
  value: L.length,
188
- label: D("devportal.organizations", "Organizations")
189
+ label: w("devportal.organizations", "Organizations")
189
190
  })
190
191
  ] })
191
192
  }),
192
- /* @__PURE__ */ _(k, {
193
- title: D("devportal.recentListings", "Recent Listings"),
194
- action: V.length > 0 ? /* @__PURE__ */ v("button", {
193
+ /* @__PURE__ */ v(A, {
194
+ title: w("devportal.recentListings", "Recent Listings"),
195
+ action: V.length > 0 ? /* @__PURE__ */ y("button", {
195
196
  onClick: () => X("/seller/items"),
196
197
  className: "inline-flex items-center gap-1 text-sm font-medium text-primary hover:underline",
197
- children: [D("devportal.viewAll", "View all"), /* @__PURE__ */ _(c, { size: 14 })]
198
+ children: [w("devportal.viewAll", "View all"), /* @__PURE__ */ v(l, { size: 14 })]
198
199
  }) : void 0,
199
- children: G || F ? /* @__PURE__ */ _("div", {
200
+ children: G || F ? /* @__PURE__ */ v("div", {
200
201
  className: "flex items-center justify-center py-12",
201
- children: /* @__PURE__ */ _(p, { className: "h-6 w-6 animate-spin text-text-secondary" })
202
- }) : V.length > 0 ? /* @__PURE__ */ _("div", {
202
+ children: /* @__PURE__ */ v(m, { className: "h-6 w-6 animate-spin text-text-secondary" })
203
+ }) : V.length > 0 ? /* @__PURE__ */ v("div", {
203
204
  className: "grid gap-4 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3",
204
- children: V.slice(0, 3).map((e) => /* @__PURE__ */ _(A, {
205
+ children: V.slice(0, 3).map((e) => /* @__PURE__ */ v(j, {
205
206
  product: e,
206
207
  onClick: () => X("/seller/items")
207
208
  }, e.id))
208
- }) : /* @__PURE__ */ _(t, {
209
+ }) : /* @__PURE__ */ v(t, {
209
210
  illustration: "empty-data",
210
- title: D("devportal.listYourFirstItem", "List your first item"),
211
- description: D("devportal.addPhysicalProductsToYourStore", "Add physical products to your store and they will appear here. Your seller organization is set up automatically the first time you list an item."),
212
- action: /* @__PURE__ */ v("button", {
211
+ title: w("devportal.listYourFirstItem", "List your first item"),
212
+ description: w("devportal.addPhysicalProductsToYourStore", "Add physical products to your store and they will appear here. Your seller organization is set up automatically the first time you list an item."),
213
+ action: /* @__PURE__ */ y("button", {
213
214
  onClick: () => X("/seller/items/new"),
214
215
  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",
215
- children: [/* @__PURE__ */ _(h, { size: 16 }), D("devportal.listAnItem", "List an Item")]
216
+ children: [/* @__PURE__ */ v(g, { size: 16 }), w("devportal.listAnItem", "List an Item")]
216
217
  })
217
218
  })
218
219
  }),
219
- (G || L.length > 0) && /* @__PURE__ */ _(k, {
220
- title: D("devportal.yourOrganizations", "Your Organizations"),
221
- action: L.length > 0 ? /* @__PURE__ */ v("button", {
220
+ (G || L.length > 0) && /* @__PURE__ */ v(A, {
221
+ title: w("devportal.yourOrganizations", "Your Organizations"),
222
+ action: L.length > 0 ? /* @__PURE__ */ y("button", {
222
223
  onClick: () => X("/seller/organizations"),
223
224
  className: "inline-flex items-center gap-1 text-sm font-medium text-primary hover:underline",
224
- children: [D("devportal.viewAll", "View all"), /* @__PURE__ */ _(c, { size: 14 })]
225
+ children: [w("devportal.viewAll", "View all"), /* @__PURE__ */ v(l, { size: 14 })]
225
226
  }) : void 0,
226
- children: G ? /* @__PURE__ */ _("div", {
227
+ children: G ? /* @__PURE__ */ v("div", {
227
228
  className: "flex items-center justify-center py-12",
228
- children: /* @__PURE__ */ _(p, { className: "h-6 w-6 animate-spin text-text-secondary" })
229
- }) : /* @__PURE__ */ _("div", {
229
+ children: /* @__PURE__ */ v(m, { className: "h-6 w-6 animate-spin text-text-secondary" })
230
+ }) : /* @__PURE__ */ v("div", {
230
231
  className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3",
231
- children: L.slice(0, 3).map((e) => /* @__PURE__ */ _(j, {
232
+ children: L.slice(0, 3).map((e) => /* @__PURE__ */ v(M, {
232
233
  org: e,
233
234
  currency: U[e.id] ?? "USD",
234
235
  onClick: () => X(`/seller/organizations/${e.id}`)
@@ -239,34 +240,34 @@ var E = "\n query SellerDashboardProducts($publisherId: String!) {\n product
239
240
  })
240
241
  })
241
242
  });
242
- }, O = ({ icon: e, value: t, label: n }) => /* @__PURE__ */ v("div", {
243
+ }, k = ({ icon: e, value: t, label: n }) => /* @__PURE__ */ y("div", {
243
244
  className: "flex items-center gap-1.5",
244
245
  children: [
245
- /* @__PURE__ */ _("span", {
246
+ /* @__PURE__ */ v("span", {
246
247
  className: "text-text-muted",
247
248
  children: e
248
249
  }),
249
- /* @__PURE__ */ _("span", {
250
+ /* @__PURE__ */ v("span", {
250
251
  className: "text-sm font-semibold tabular-nums",
251
252
  children: t
252
253
  }),
253
- /* @__PURE__ */ _("span", {
254
+ /* @__PURE__ */ v("span", {
254
255
  className: "text-sm text-text-secondary",
255
256
  children: n
256
257
  })
257
258
  ]
258
- }), k = ({ title: e, action: t, children: n }) => /* @__PURE__ */ v("section", {
259
+ }), A = ({ title: e, action: t, children: n }) => /* @__PURE__ */ y("section", {
259
260
  className: "flex flex-col gap-4",
260
- children: [/* @__PURE__ */ v("div", {
261
+ children: [/* @__PURE__ */ y("div", {
261
262
  className: "flex items-center justify-between",
262
- children: [/* @__PURE__ */ _("h2", {
263
+ children: [/* @__PURE__ */ v("h2", {
263
264
  className: "text-sm font-semibold uppercase tracking-wider text-text-secondary",
264
265
  children: e
265
266
  }), t]
266
267
  }), n]
267
- }), A = ({ product: e, onClick: t }) => {
268
- let n = S[e.status] ?? S.DRAFT;
269
- return /* @__PURE__ */ v(b, {
268
+ }), j = ({ product: e, onClick: t }) => {
269
+ let n = C[e.status] ?? C.DRAFT;
270
+ return /* @__PURE__ */ y(x, {
270
271
  treatment: "insight",
271
272
  role: "button",
272
273
  tabIndex: 0,
@@ -275,49 +276,50 @@ var E = "\n query SellerDashboardProducts($publisherId: String!) {\n product
275
276
  onKeyDown: (e) => {
276
277
  (e.key === "Enter" || e.key === " ") && (e.preventDefault(), t());
277
278
  },
278
- children: [/* @__PURE__ */ v("div", {
279
+ children: [/* @__PURE__ */ y("div", {
279
280
  className: "flex items-center gap-3 mb-4",
280
281
  children: [
281
- e.icon ? /* @__PURE__ */ _("img", {
282
+ /* @__PURE__ */ v(o, {
282
283
  src: e.icon,
283
284
  alt: e.name,
284
- className: "h-10 w-10 rounded-xl object-cover shrink-0"
285
- }) : /* @__PURE__ */ _("div", {
286
- className: "flex h-10 w-10 items-center justify-center rounded-xl bg-action-primary-bg/15 text-primary shrink-0",
287
- children: /* @__PURE__ */ _(m, { size: 20 })
285
+ className: "h-10 w-10 rounded-xl object-cover shrink-0",
286
+ fallback: /* @__PURE__ */ v("div", {
287
+ className: "flex h-10 w-10 items-center justify-center rounded-xl bg-action-primary-bg/15 text-primary shrink-0",
288
+ children: /* @__PURE__ */ v(h, { size: 20 })
289
+ })
288
290
  }),
289
- /* @__PURE__ */ v("div", {
291
+ /* @__PURE__ */ y("div", {
290
292
  className: "min-w-0 flex-1",
291
- children: [/* @__PURE__ */ _("p", {
293
+ children: [/* @__PURE__ */ v("p", {
292
294
  className: "font-semibold truncate text-text-primary",
293
295
  children: e.name
294
- }), /* @__PURE__ */ _("p", {
296
+ }), /* @__PURE__ */ v("p", {
295
297
  className: "text-xs text-text-secondary mt-0.5",
296
- children: C(e.price, e.currency)
298
+ children: w(e.price, e.currency)
297
299
  })]
298
300
  }),
299
- /* @__PURE__ */ _("span", {
301
+ /* @__PURE__ */ v("span", {
300
302
  className: `shrink-0 rounded-full px-2.5 py-0.5 text-xs font-medium ${n.className}`,
301
303
  children: n.label
302
304
  })
303
305
  ]
304
- }), /* @__PURE__ */ v("div", {
306
+ }), /* @__PURE__ */ y("div", {
305
307
  className: "flex items-center gap-2 text-sm",
306
- children: [/* @__PURE__ */ _(m, {
308
+ children: [/* @__PURE__ */ v(h, {
307
309
  size: 12,
308
310
  className: "text-text-muted shrink-0"
309
- }), /* @__PURE__ */ _("span", {
311
+ }), /* @__PURE__ */ v("span", {
310
312
  className: e.stockQuantity === 0 ? "text-status-error-text" : "text-text-secondary",
311
313
  children: e.stockQuantity === 0 ? "Out of stock" : `${e.stockQuantity} in stock`
312
314
  })]
313
315
  })]
314
316
  });
315
- }, j = ({ org: e, currency: t, onClick: n }) => {
316
- let { t: r } = y(), a = (e, t) => {
317
+ }, M = ({ org: e, currency: t, onClick: n }) => {
318
+ let { t: r } = b(), a = (e, t) => {
317
319
  let n = r(e);
318
320
  return n === e ? t : n;
319
321
  }, o = e.name.split(" ").map((e) => e[0]).join("").slice(0, 2).toUpperCase();
320
- return /* @__PURE__ */ v(b, {
322
+ return /* @__PURE__ */ y(x, {
321
323
  treatment: "insight",
322
324
  role: "button",
323
325
  tabIndex: 0,
@@ -326,23 +328,23 @@ var E = "\n query SellerDashboardProducts($publisherId: String!) {\n product
326
328
  onKeyDown: (e) => {
327
329
  (e.key === "Enter" || e.key === " ") && (e.preventDefault(), n());
328
330
  },
329
- children: [/* @__PURE__ */ v("div", {
331
+ children: [/* @__PURE__ */ y("div", {
330
332
  className: "flex items-center gap-3 mb-4",
331
333
  children: [
332
- e.logoUrl ? /* @__PURE__ */ _("img", {
334
+ e.logoUrl ? /* @__PURE__ */ v("img", {
333
335
  src: e.logoUrl,
334
336
  alt: e.name,
335
337
  className: "h-10 w-10 rounded-xl object-cover"
336
- }) : /* @__PURE__ */ _("div", {
338
+ }) : /* @__PURE__ */ v("div", {
337
339
  className: "flex h-10 w-10 items-center justify-center rounded-xl bg-action-primary-bg/15 text-primary text-sm font-bold",
338
340
  children: o
339
341
  }),
340
- /* @__PURE__ */ v("div", {
342
+ /* @__PURE__ */ y("div", {
341
343
  className: "min-w-0 flex-1",
342
- children: [/* @__PURE__ */ _("p", {
344
+ children: [/* @__PURE__ */ v("p", {
343
345
  className: "font-semibold truncate text-text-primary",
344
346
  children: e.name
345
- }), /* @__PURE__ */ v("p", {
347
+ }), /* @__PURE__ */ y("p", {
346
348
  className: "text-xs text-text-secondary mt-0.5",
347
349
  children: [
348
350
  e.publishedApps ?? 0,
@@ -351,22 +353,22 @@ var E = "\n query SellerDashboardProducts($publisherId: String!) {\n product
351
353
  ]
352
354
  })]
353
355
  }),
354
- /* @__PURE__ */ _(c, {
356
+ /* @__PURE__ */ v(l, {
355
357
  size: 15,
356
358
  className: "text-text-muted shrink-0"
357
359
  })
358
360
  ]
359
- }), /* @__PURE__ */ _("div", {
361
+ }), /* @__PURE__ */ v("div", {
360
362
  className: "grid grid-cols-1 gap-3",
361
- children: /* @__PURE__ */ v("div", {
363
+ children: /* @__PURE__ */ y("div", {
362
364
  className: "flex items-center gap-2 rounded-lg bg-bg-muted px-3 py-2",
363
- children: [/* @__PURE__ */ _(f, {
365
+ children: [/* @__PURE__ */ v(p, {
364
366
  size: 12,
365
367
  className: "text-text-muted shrink-0"
366
- }), /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("p", {
368
+ }), /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
367
369
  className: "text-[11px] text-text-secondary leading-none mb-0.5",
368
370
  children: a("devportal.revenue", "Revenue")
369
- }), /* @__PURE__ */ _("p", {
371
+ }), /* @__PURE__ */ v("p", {
370
372
  className: "text-sm font-semibold tabular-nums",
371
373
  children: i(e.totalRevenue ?? 0, t)
372
374
  })] })]
@@ -374,6 +376,6 @@ var E = "\n query SellerDashboardProducts($publisherId: String!) {\n product
374
376
  })]
375
377
  });
376
378
  };
377
- export { D as SellerDashboardPage };
379
+ export { O as SellerDashboardPage };
378
380
 
379
381
  //# sourceMappingURL=SellerDashboardPage.js.map