@burdenoff/microfe-store 2026.624.3 → 2026.624.6
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/StoreRoutes.js +3 -3
- package/dist/StoreRoutes.js.map +1 -1
- package/dist/components/AccessDenied.js +3 -3
- package/dist/components/AccessDenied.js.map +1 -1
- package/dist/components/InstallAppModal.js +119 -106
- package/dist/components/InstallAppModal.js.map +1 -1
- package/dist/components/cart/CartDrawer.js +6 -6
- package/dist/components/cart/CartDrawer.js.map +1 -1
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/errors/CombinedGraphQLErrors.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/errors/utils.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/errors/utils.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/link/core/ApolloLink.js +2 -2
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/link/core/ApolloLink.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/link/subscriptions/index.js +2 -2
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/link/subscriptions/index.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/link/utils/createOperation.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/link/utils/createOperation.js.map +1 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/caching/sizes.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/graphql/print.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/graphql/print.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/caches.js +2 -2
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/caches.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/checkDocument.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/checkDocument.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/getMainDefinition.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getMainDefinition.js.map +1 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js +9 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/getOperationDefinition.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getOperationDefinition.js.map +1 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getOperationName.js +8 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getOperationName.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/globals/global.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/globals/global.js.map +1 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/globals/maybe.js +10 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/globals/maybe.js.map +1 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/isNonNullObject.js +8 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/isNonNullObject.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/makeUniqueId.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/makeUniqueId.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/memoize.js +2 -2
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/memoize.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/stringifyForDisplay.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/stringifyForDisplay.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/invariant/index.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/invariant/index.js.map +1 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/version.js +6 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/version.js.map +1 -0
- package/dist/node_modules/{@wry → .bun/@wry_caches@1.0.1/node_modules/@wry}/caches/lib/weak.js +1 -1
- package/dist/node_modules/.bun/@wry_caches@1.0.1/node_modules/@wry/caches/lib/weak.js.map +1 -0
- package/dist/node_modules/{@wry → .bun/@wry_trie@0.5.0/node_modules/@wry}/trie/lib/index.js +1 -1
- package/dist/node_modules/.bun/@wry_trie@0.5.0/node_modules/@wry/trie/lib/index.js.map +1 -0
- package/dist/node_modules/{graphql-ws → .bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws}/dist/client.js +1 -1
- package/dist/node_modules/.bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws/dist/client.js.map +1 -0
- package/dist/node_modules/{graphql-ws → .bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws}/dist/common-CGW11Fyb.js +1 -1
- package/dist/node_modules/.bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws/dist/common-CGW11Fyb.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/NotificationFactories.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/NotificationFactories.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/Observable.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/Observable.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/Subscriber.js +2 -2
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/Subscriber.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/Subscription.js +2 -2
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/Subscription.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/config.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/config.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/observable/empty.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/observable/empty.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/scheduler/timeoutProvider.js +2 -2
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/scheduler/timeoutProvider.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/symbol/observable.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/symbol/observable.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/util/UnsubscriptionError.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/UnsubscriptionError.js.map +1 -0
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js +11 -0
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/util/createErrorClass.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/createErrorClass.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/util/errorContext.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/errorContext.js.map +1 -0
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/identity.js +8 -0
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/identity.js.map +1 -0
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/isFunction.js +8 -0
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/isFunction.js.map +1 -0
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/noop.js +6 -0
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/noop.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/util/pipe.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/pipe.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/util/reportUnhandledError.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/reportUnhandledError.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/tslib@2.8.1}/node_modules/tslib/tslib.es6.js +1 -1
- package/dist/node_modules/.bun/tslib@2.8.1/node_modules/tslib/tslib.es6.js.map +1 -0
- package/dist/pages/AdminDashboardPage.js +1 -1
- package/dist/pages/AdminDashboardPage.js.map +1 -1
- package/dist/pages/AdminStoresPage.js +372 -390
- package/dist/pages/AdminStoresPage.js.map +1 -1
- package/dist/pages/AdminSubmissionsQueuePage.js +144 -130
- package/dist/pages/AdminSubmissionsQueuePage.js.map +1 -1
- package/dist/pages/AppSettingsPage.js +292 -65
- package/dist/pages/AppSettingsPage.js.map +1 -1
- package/dist/pages/InstalledAppsPage.js +98 -69
- package/dist/pages/InstalledAppsPage.js.map +1 -1
- package/dist/pages/MarketplaceHomePage.js +1 -1
- package/dist/pages/MarketplaceHomePage.js.map +1 -1
- package/dist/providers/StoreProvider.js +3 -3
- package/package.json +2 -2
- package/dist/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js.map +0 -1
- package/dist/node_modules/@apollo/client/errors/utils.js.map +0 -1
- package/dist/node_modules/@apollo/client/link/core/ApolloLink.js.map +0 -1
- package/dist/node_modules/@apollo/client/link/subscriptions/index.js.map +0 -1
- package/dist/node_modules/@apollo/client/link/utils/createOperation.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/caching/sizes.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/graphql/print.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/caches.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/checkDocument.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/getMainDefinition.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js +0 -9
- package/dist/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/getOperationDefinition.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/getOperationName.js +0 -8
- package/dist/node_modules/@apollo/client/utilities/internal/getOperationName.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/globals/global.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/globals/maybe.js +0 -10
- package/dist/node_modules/@apollo/client/utilities/internal/globals/maybe.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/isNonNullObject.js +0 -8
- package/dist/node_modules/@apollo/client/utilities/internal/isNonNullObject.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/makeUniqueId.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/memoize.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/stringifyForDisplay.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/invariant/index.js.map +0 -1
- package/dist/node_modules/@apollo/client/version.js +0 -6
- package/dist/node_modules/@apollo/client/version.js.map +0 -1
- package/dist/node_modules/@wry/caches/lib/weak.js.map +0 -1
- package/dist/node_modules/@wry/trie/lib/index.js.map +0 -1
- package/dist/node_modules/graphql-ws/dist/client.js.map +0 -1
- package/dist/node_modules/graphql-ws/dist/common-CGW11Fyb.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/NotificationFactories.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/Observable.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/Subscriber.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/Subscription.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/config.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/observable/empty.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/scheduler/timeoutProvider.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/symbol/observable.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/UnsubscriptionError.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js +0 -11
- package/dist/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/createErrorClass.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/errorContext.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/identity.js +0 -8
- package/dist/node_modules/rxjs/dist/esm5/internal/util/identity.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/isFunction.js +0 -8
- package/dist/node_modules/rxjs/dist/esm5/internal/util/isFunction.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/noop.js +0 -6
- package/dist/node_modules/rxjs/dist/esm5/internal/util/noop.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/pipe.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/reportUnhandledError.js.map +0 -1
- package/dist/node_modules/rxjs/node_modules/tslib/tslib.es6.js.map +0 -1
- /package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/caching/sizes.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarketplaceHomePage.js","names":[],"sources":["../../src/pages/MarketplaceHomePage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useState, useCallback, useMemo, useId, useEffect, useRef } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n Search,\n Star,\n Download,\n ChevronRight,\n ChevronDown,\n Sparkles,\n TrendingUp,\n Clock,\n Bot,\n Brain,\n LayoutDashboard,\n GitBranch,\n Box,\n Puzzle,\n ShoppingCart,\n X,\n AlertCircle,\n Gift,\n Filter,\n SlidersHorizontal,\n Loader2,\n FileCode2,\n Database,\n type LucideIcon,\n} from 'lucide-react';\nimport { useDebounce } from '@burdenoff/fe-libs/shared/hooks';\nimport { useEventBus } from '@burdenoff/fe-libs/shared/events';\nimport { useStore } from '../providers/StoreProvider';\nimport { useCart } from '../hooks/useCart';\nimport { CartDrawer } from '../components/cart/CartDrawer';\nimport {\n useHomeGroupedProducts,\n useBrowseStoreWithContext,\n type StoreProduct,\n} from '../hooks/useStoreGraphQL';\nimport type { BrowseStoreInput } from '../generated/global-types';\nimport { StoreSortBy, PricingModel, ProductNature } from '../generated/global-types';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\n// ========================================\n// Helper Types and Functions\n// ========================================\n\ntype ProductTypeKey =\n | 'BOTAPP'\n | 'AGENT'\n | 'CONSOLE'\n | 'WORKFLOW'\n | 'NODE'\n | 'WIDGET'\n | 'VIBEMODULE'\n | 'DASHBOARD'\n | 'PARSER'\n | 'DATASINK'\n | 'APP'\n | 'TEMPLATE'\n | 'INTEGRATION'\n | 'EXTENSION'\n | 'THEME'\n | 'PLUGIN'\n | 'COMPONENT'\n | string;\n\nconst formatDownloads = (count: number): string => {\n if (count >= 1000000) return `${(count / 1000000).toFixed(1)}M`;\n if (count >= 1000) return `${(count / 1000).toFixed(1)}K`;\n return count.toString();\n};\n\nconst getPriceDisplay = (product: StoreProduct): string => {\n if (product.pricingModel === 'FREE') return 'Free';\n if (product.price === 0) return 'Free';\n return `$${product.price}`;\n};\n\nconst getProductColor = (type: ProductTypeKey): string => {\n const colors: Record<string, string> = {\n BOTAPP: 'var(--color-accent-blue)',\n AGENT: 'var(--color-accent-purple)',\n CONSOLE: 'var(--color-accent-teal)',\n WORKFLOW: 'var(--color-status-warning-bg)',\n NODE: 'var(--color-status-error-bg)',\n WIDGET: 'var(--color-accent-purple)',\n VIBEMODULE: 'var(--color-accent-blue)',\n DASHBOARD: 'var(--color-accent-blue)',\n PARSER: 'var(--color-status-warning-bg)',\n DATASINK: 'var(--color-status-success-bg)',\n APP: 'var(--color-accent-indigo)',\n TEMPLATE: 'var(--color-accent-teal)',\n INTEGRATION: 'var(--color-status-warning-bg)',\n EXTENSION: 'var(--color-accent-purple)',\n THEME: 'var(--color-accent-purple)',\n PLUGIN: 'var(--color-status-success-bg)',\n COMPONENT: 'var(--color-accent-blue)',\n };\n return colors[type] || 'var(--color-text-muted)';\n};\n\n// Helper to get translucent background color from a token\nconst getProductBgColor = (type: ProductTypeKey): string => {\n const color = getProductColor(type);\n return `color-mix(in srgb, ${color}, transparent 85%)`;\n};\n\n// Component wrapper to render type icons\ninterface ProductTypeIconProps {\n type: ProductTypeKey;\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst TYPE_ICONS: Record<string, LucideIcon> = {\n BOTAPP: Bot,\n AGENT: Brain,\n CONSOLE: LayoutDashboard,\n WORKFLOW: GitBranch,\n NODE: Box,\n WIDGET: Puzzle,\n VIBEMODULE: Puzzle,\n DASHBOARD: LayoutDashboard,\n PARSER: FileCode2,\n DATASINK: Database,\n APP: Box,\n TEMPLATE: LayoutDashboard,\n INTEGRATION: GitBranch,\n EXTENSION: Puzzle,\n THEME: Puzzle,\n PLUGIN: Puzzle,\n COMPONENT: Box,\n};\n\nconst ProductTypeIcon: FC<ProductTypeIconProps> = ({ type, className, style }) => {\n const IconComponent = TYPE_ICONS[type] || Box;\n return <IconComponent className={className} style={style} />;\n};\n\n// ========================================\n// App Card Component\n// ========================================\n\ninterface AppCardProps {\n product: StoreProduct;\n onClick: () => void;\n variant?: 'default' | 'compact' | 'featured';\n}\n\nconst AppCard: FC<AppCardProps> = ({ product, onClick, variant = 'default' }) => {\n const productColor = getProductColor(product.type);\n\n if (variant === 'featured') {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className=\"group relative flex size-full cursor-pointer flex-col overflow-hidden rounded-2xl border border-border-default bg-gradient-to-br from-bg-surface to-bg-sunken p-6 text-left transition-all hover:border-action-primary-border hover:shadow-lg\"\n >\n {product.featured && (\n <div className=\"absolute right-4 top-4 flex items-center gap-1 rounded-full bg-status-warning-bg-subtle px-2 py-1 text-xs font-medium text-status-warning-text\">\n <Sparkles className=\"size-3\" />\n Featured\n </div>\n )}\n <div className=\"flex items-start gap-4\">\n <div\n className=\"flex size-16 flex-shrink-0 items-center justify-center rounded-2xl\"\n style={{ backgroundColor: getProductBgColor(product.type) }}\n >\n {product.icon ? (\n <img\n src={product.icon}\n alt={product.name}\n className=\"size-10 rounded-lg object-cover\"\n />\n ) : (\n <ProductTypeIcon\n type={product.type}\n className=\"size-10\"\n style={{ color: productColor }}\n />\n )}\n </div>\n <div className=\"flex-1 overflow-hidden\">\n <h3 className=\"truncate text-lg font-semibold text-text-primary group-hover:text-text-link\">\n {product.name}\n </h3>\n <p className=\"flex items-center gap-2 text-sm text-text-muted\">\n <ProductTypeIcon type={product.type} className=\"size-3.5\" />\n {product.category || product.type}\n </p>\n </div>\n </div>\n <p className=\"mt-4 line-clamp-2 flex-1 text-sm text-text-muted\">\n {product.description || 'No description available'}\n </p>\n <div className=\"mt-4 flex items-center justify-between border-t border-border-default pt-4\">\n <div className=\"flex items-center gap-3\">\n <span className=\"flex items-center gap-1 text-sm text-text-muted\">\n <Star className=\"size-4 fill-current text-status-warning-text\" />\n {(product.rating ?? 0).toFixed(1)}\n </span>\n <span className=\"flex items-center gap-1 text-sm text-text-muted\">\n <Download className=\"size-4\" />\n {formatDownloads(product.downloads)}\n </span>\n </div>\n <span className=\"rounded-full bg-action-primary-bg/10 px-3 py-1 text-sm font-medium text-text-link\">\n {getPriceDisplay(product)}\n </span>\n </div>\n </button>\n );\n }\n\n if (variant === 'compact') {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className=\"group flex cursor-pointer items-center gap-3 rounded-xl border border-transparent p-3 text-left transition-all hover:border-border-default hover:bg-bg-surface\"\n >\n <div\n className=\"flex size-12 flex-shrink-0 items-center justify-center rounded-xl\"\n style={{ backgroundColor: getProductBgColor(product.type) }}\n >\n {product.icon ? (\n <img src={product.icon} alt={product.name} className=\"size-8 rounded-lg object-cover\" />\n ) : (\n <ProductTypeIcon\n type={product.type}\n className=\"size-8\"\n style={{ color: productColor }}\n />\n )}\n </div>\n <div className=\"flex-1 overflow-hidden\">\n <h4 className=\"truncate font-medium text-text-primary group-hover:text-text-link\">\n {product.name}\n </h4>\n <p className=\"truncate text-xs text-text-muted\">\n {product.category || product.type} · {(product.rating ?? 0).toFixed(1)} ★\n </p>\n </div>\n <span className=\"text-xs font-medium text-text-muted\">{getPriceDisplay(product)}</span>\n </button>\n );\n }\n\n // Default variant\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className=\"group flex cursor-pointer flex-col overflow-hidden rounded-xl border border-border-default bg-bg-surface p-4 text-left transition-all hover:border-action-primary-border hover:shadow-md\"\n >\n <div className=\"flex items-start gap-3\">\n <div\n className=\"flex size-14 flex-shrink-0 items-center justify-center rounded-xl\"\n style={{ backgroundColor: getProductBgColor(product.type) }}\n >\n {product.icon ? (\n <img src={product.icon} alt={product.name} className=\"size-9 rounded-lg object-cover\" />\n ) : (\n <ProductTypeIcon\n type={product.type}\n className=\"size-9\"\n style={{ color: productColor }}\n />\n )}\n </div>\n <div className=\"flex-1 overflow-hidden\">\n <h4 className=\"truncate font-semibold text-text-primary group-hover:text-text-link\">\n {product.name}\n </h4>\n <p className=\"flex items-center gap-1.5 text-xs text-text-muted\">\n <ProductTypeIcon type={product.type} className=\"size-3\" />\n {product.category || product.type}\n </p>\n </div>\n </div>\n <p className=\"mt-3 line-clamp-2 text-sm text-text-muted\">\n {product.description || 'No description available'}\n </p>\n <div className=\"mt-3 flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <span className=\"flex items-center gap-0.5 text-xs text-text-muted\">\n <Star className=\"size-3.5 fill-current text-status-warning-text\" />\n {(product.rating ?? 0).toFixed(1)}\n </span>\n <span className=\"text-xs text-text-muted\">·</span>\n <span className=\"text-xs text-text-muted\">\n {formatDownloads(product.downloads)} downloads\n </span>\n </div>\n <span className=\"text-xs font-semibold text-text-link\">{getPriceDisplay(product)}</span>\n </div>\n </button>\n );\n};\n\n// ========================================\n// Section Header Component\n// ========================================\n\ninterface SectionHeaderProps {\n icon: typeof Sparkles;\n title: string;\n subtitle?: string;\n onViewAll?: () => void;\n}\n\nconst SectionHeader: FC<SectionHeaderProps> = ({ icon: Icon, title, subtitle, onViewAll }) => (\n <div className=\"mb-4 flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex size-10 items-center justify-center rounded-xl bg-action-primary-bg/10\">\n <Icon className=\"size-5 text-text-link\" />\n </div>\n <div>\n <h2 className=\"text-lg font-semibold text-text-primary\">{title}</h2>\n {subtitle && <p className=\"text-sm text-text-muted\">{subtitle}</p>}\n </div>\n </div>\n {onViewAll && (\n <button\n type=\"button\"\n onClick={onViewAll}\n className=\"cursor-pointer flex items-center gap-1 text-sm font-medium text-text-link hover:underline\"\n >\n View all\n <ChevronRight className=\"size-4\" />\n </button>\n )}\n </div>\n);\n\n// ========================================\n// Category Chip Component\n// ========================================\n\ninterface CategoryChipProps {\n typeId: ProductTypeKey;\n name: string;\n count: number;\n active?: boolean;\n onClick: () => void;\n}\n\nconst CategoryChip: FC<CategoryChipProps> = ({ typeId, name, count, active, onClick }) => (\n <button\n type=\"button\"\n onClick={onClick}\n className={`flex cursor-pointer items-center gap-2 rounded-full px-4 py-2 text-sm font-medium transition-all ${\n active\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-surface text-text-primary hover:bg-bg-sunken'\n }`}\n >\n <ProductTypeIcon type={typeId} className=\"size-4\" />\n {name}\n <span\n className={`rounded-full px-1.5 py-0.5 text-xs ${active ? 'bg-bg-surface/20' : 'bg-bg-sunken'}`}\n >\n {count}\n </span>\n </button>\n);\n\n// ========================================\n// Hero Section Component\n// ========================================\n\ninterface HeroSectionProps {\n featuredProducts: StoreProduct[];\n onProductClick: (product: StoreProduct) => void;\n /** Optional tour anchor placed on the hero root (avoids an extra wrapper div). */\n dataTour?: string;\n}\n\nconst HeroSection: FC<HeroSectionProps> = ({ featuredProducts, onProductClick, dataTour }) => {\n const [activeIndex, setActiveIndex] = useState(0);\n const heroProduct = featuredProducts[activeIndex] || featuredProducts[0];\n\n if (!heroProduct) return null;\n\n const productColor = getProductColor(heroProduct.type);\n\n return (\n <div\n data-tour={dataTour}\n className=\"relative overflow-hidden rounded-2xl bg-gradient-to-r from-bg-surface via-bg-sunken to-bg-surface p-8\"\n >\n <div\n className=\"absolute inset-0 opacity-10\"\n style={{\n background: `linear-gradient(135deg, ${productColor} 0%, transparent 50%)`,\n }}\n />\n <div className=\"relative z-10 flex items-center gap-8\">\n <div className=\"flex-1\">\n <div className=\"mb-4 flex items-center gap-2\">\n <span className=\"flex items-center gap-1 rounded-full bg-status-warning-bg-subtle px-3 py-1 text-xs font-semibold text-status-warning-text\">\n <Sparkles className=\"size-3\" />\n Featured App\n </span>\n <span className=\"rounded-full bg-action-primary-bg/10 px-3 py-1 text-xs font-medium text-text-link\">\n {heroProduct.category || heroProduct.type}\n </span>\n </div>\n <h1 className=\"mb-3 text-3xl font-bold text-text-primary\">{heroProduct.name}</h1>\n <p className=\"mb-6 max-w-xl text-text-muted\">\n {heroProduct.description || 'No description available'}\n </p>\n <div className=\"mb-6 flex items-center gap-4\">\n <span className=\"flex items-center gap-1 text-sm\">\n <Star className=\"size-5 fill-current text-status-warning-text\" />\n <span className=\"font-semibold text-text-primary\">\n {(heroProduct.rating ?? 0).toFixed(1)}\n </span>\n <span className=\"text-text-muted\">({heroProduct.reviewCount} reviews)</span>\n </span>\n <span className=\"flex items-center gap-1 text-sm text-text-muted\">\n <Download className=\"size-4\" />\n {heroProduct.downloads.toLocaleString()} downloads\n </span>\n </div>\n <button\n type=\"button\"\n onClick={() => onProductClick(heroProduct)}\n className=\"cursor-pointer rounded-lg bg-action-primary-bg px-6 py-3 font-semibold text-action-primary-text transition-opacity hover:opacity-90\"\n >\n View Details\n </button>\n </div>\n <div className=\"hidden flex-shrink-0 lg:block\">\n <div\n className=\"flex size-48 items-center justify-center rounded-3xl shadow-lg\"\n style={{ backgroundColor: getProductBgColor(heroProduct.type) }}\n >\n {heroProduct.icon ? (\n <img\n src={heroProduct.icon}\n alt={heroProduct.name}\n className=\"size-32 rounded-2xl object-cover\"\n />\n ) : (\n <ProductTypeIcon\n type={heroProduct.type}\n className=\"size-32\"\n style={{ color: productColor }}\n />\n )}\n </div>\n </div>\n </div>\n {/* Featured App Selector */}\n {featuredProducts.length > 1 && (\n <div className=\"relative z-10 mt-6 flex gap-2\">\n {featuredProducts.map((product, index) => (\n <button\n type=\"button\"\n key={product.id}\n onClick={() => setActiveIndex(index)}\n className={`h-2 w-8 rounded-full transition-all ${\n index === activeIndex\n ? 'bg-action-primary-bg'\n : 'bg-border-default hover:bg-action-primary-border'\n }`}\n aria-label={`View ${product.name}`}\n />\n ))}\n </div>\n )}\n </div>\n );\n};\n\n// ========================================\n// Loading Skeleton Components\n// ========================================\n\nconst ProductCardSkeleton: FC<{ variant?: 'default' | 'compact' | 'featured' }> = ({\n variant = 'default',\n}) => {\n if (variant === 'featured') {\n return (\n <div className=\"h-full animate-pulse rounded-2xl border border-border-default bg-bg-surface p-6\">\n <div className=\"flex items-start gap-4\">\n <div className=\"size-16 rounded-2xl bg-bg-sunken\" />\n <div className=\"flex-1 space-y-2\">\n <div className=\"h-5 w-3/4 rounded bg-bg-sunken\" />\n <div className=\"h-4 w-1/2 rounded bg-bg-sunken\" />\n </div>\n </div>\n <div className=\"mt-4 space-y-2\">\n <div className=\"h-4 w-full rounded bg-bg-sunken\" />\n <div className=\"h-4 w-2/3 rounded bg-bg-sunken\" />\n </div>\n </div>\n );\n }\n\n if (variant === 'compact') {\n return (\n <div className=\"flex animate-pulse items-center gap-3 p-3\">\n <div className=\"size-12 rounded-xl bg-bg-sunken\" />\n <div className=\"flex-1 space-y-2\">\n <div className=\"h-4 w-3/4 rounded bg-bg-sunken\" />\n <div className=\"h-3 w-1/2 rounded bg-bg-sunken\" />\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"animate-pulse rounded-xl border border-border-default bg-bg-surface p-4\">\n <div className=\"flex items-start gap-3\">\n <div className=\"size-14 rounded-xl bg-bg-sunken\" />\n <div className=\"flex-1 space-y-2\">\n <div className=\"h-4 w-3/4 rounded bg-bg-sunken\" />\n <div className=\"h-3 w-1/2 rounded bg-bg-sunken\" />\n </div>\n </div>\n <div className=\"mt-3 space-y-2\">\n <div className=\"h-3 w-full rounded bg-bg-sunken\" />\n <div className=\"h-3 w-2/3 rounded bg-bg-sunken\" />\n </div>\n </div>\n );\n};\n\n// Hero Section Skeleton\nconst HeroSkeleton: FC = () => (\n <div className=\"animate-pulse rounded-2xl bg-gradient-to-r from-bg-surface via-bg-sunken to-bg-surface p-8\">\n <div className=\"flex items-center gap-8\">\n <div className=\"flex-1 space-y-4\">\n <div className=\"flex gap-2\">\n <div className=\"h-6 w-24 rounded-full bg-bg-sunken\" />\n <div className=\"h-6 w-20 rounded-full bg-bg-sunken\" />\n </div>\n <div className=\"h-9 w-3/4 rounded bg-bg-sunken\" />\n <div className=\"space-y-2\">\n <div className=\"h-4 w-full rounded bg-bg-sunken\" />\n <div className=\"h-4 w-5/6 rounded bg-bg-sunken\" />\n </div>\n <div className=\"flex gap-4\">\n <div className=\"h-5 w-24 rounded bg-bg-sunken\" />\n <div className=\"h-5 w-32 rounded bg-bg-sunken\" />\n </div>\n <div className=\"h-12 w-36 rounded-lg bg-bg-sunken\" />\n </div>\n <div className=\"hidden size-48 rounded-3xl bg-bg-sunken lg:block\" />\n </div>\n <div className=\"mt-6 flex gap-2\">\n {[...Array(3)].map((_, i) => (\n <div key={i} className=\"h-2 w-8 rounded-full bg-bg-sunken\" />\n ))}\n </div>\n </div>\n);\n\n// Category Chips Skeleton (Browse by Type)\nconst CHIP_WIDTHS = [100, 120, 90, 110, 130, 95, 115, 105];\n\nconst CategoryChipsSkeleton: FC = () => (\n <div className=\"space-y-4\">\n <div className=\"h-6 w-32 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"flex flex-wrap gap-2\">\n {CHIP_WIDTHS.map((width, i) => (\n <div\n key={i}\n className=\"h-9 animate-pulse rounded-full bg-bg-sunken\"\n style={{ width: `${width}px` }}\n />\n ))}\n </div>\n </div>\n);\n\n// Section Header Skeleton\nconst SectionHeaderSkeleton: FC = () => (\n <div className=\"mb-4 flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"size-10 animate-pulse rounded-xl bg-bg-sunken\" />\n <div className=\"space-y-1\">\n <div className=\"h-5 w-40 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"h-4 w-32 animate-pulse rounded bg-bg-sunken\" />\n </div>\n </div>\n <div className=\"h-4 w-16 animate-pulse rounded bg-bg-sunken\" />\n </div>\n);\n\n// Full Page Skeleton - shows complete loading state\nconst MarketplacePageSkeleton: FC = () => (\n <div className=\"mx-auto max-w-7xl space-y-8 p-6\">\n {/* Hero Section */}\n <HeroSkeleton />\n\n {/* Browse by Type */}\n <CategoryChipsSkeleton />\n\n {/* Most Downloaded Section */}\n <div>\n <SectionHeaderSkeleton />\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {[...Array(6)].map((_, i) => (\n <ProductCardSkeleton key={i} />\n ))}\n </div>\n </div>\n\n {/* New Releases Section */}\n <div>\n <SectionHeaderSkeleton />\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {[...Array(6)].map((_, i) => (\n <ProductCardSkeleton key={i} />\n ))}\n </div>\n </div>\n\n {/* Free Apps Section */}\n <div>\n <SectionHeaderSkeleton />\n <div className=\"grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-6\">\n {[...Array(6)].map((_, i) => (\n <ProductCardSkeleton key={i} variant=\"compact\" />\n ))}\n </div>\n </div>\n </div>\n);\n\n// ========================================\n// Filter Types\n// ========================================\n\ntype PricingFilter = 'all' | 'free' | 'paid' | 'subscription';\ntype RatingFilter = 'any' | '3' | '3.5' | '4' | '4.5';\ntype NatureFilter = 'all' | 'digital' | 'physical';\ntype SortOption =\n | 'relevance'\n | 'rating'\n | 'downloads'\n | 'newest'\n | 'price-low'\n | 'price-high'\n | 'name-asc';\n\ninterface FilterDropdownProps {\n label: string;\n value: string;\n options: { value: string; label: string }[];\n onChange: (value: string) => void;\n}\n\nconst FilterDropdown: FC<FilterDropdownProps> = ({ label, value, options, onChange }) => {\n const selectId = useId();\n\n return (\n <label\n htmlFor={selectId}\n className=\"relative inline-flex items-center gap-2 rounded-lg border border-border-default bg-bg-surface px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken focus-within:border-action-primary-border focus-within:ring-2 focus-within:ring-action-primary-border/20\"\n >\n <span className=\"sr-only\">{label}</span>\n <span className=\"text-text-muted\">{label}:</span>\n <select\n id={selectId}\n aria-label={label}\n value={value}\n onChange={(event) => onChange(event.target.value)}\n className=\"min-w-[8rem] appearance-none bg-transparent pr-6 text-sm font-medium text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]\"\n >\n {options.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n <ChevronDown className=\"pointer-events-none absolute right-3 size-4 text-text-muted\" />\n </label>\n );\n};\n\n// ========================================\n// Main Page Component\n// ========================================\n\nexport const MarketplaceHomePage: FC = () => {\n const navigate = useNavigate();\n const { basePath } = useStore();\n const { t } = useI18n();\n const searchInputId = useId();\n const bus = useEventBus();\n const {\n cartOpen,\n closeCart,\n itemCount,\n cartItems,\n subtotal,\n tax,\n total,\n updateQuantity,\n removeProduct,\n } = useCart();\n const [searchQuery, setSearchQuery] = useState('');\n const [selectedType, setSelectedType] = useState<string>('all');\n\n // Filter states\n const [pricingFilter, setPricingFilter] = useState<PricingFilter>('all');\n const [ratingFilter, setRatingFilter] = useState<RatingFilter>('any');\n const [natureFilter, setNatureFilter] = useState<NatureFilter>('all');\n const [selectedCategory, setSelectedCategory] = useState<string>('all');\n const [selectedLicense, setSelectedLicense] = useState<string>('all');\n const [featuredOnly, setFeaturedOnly] = useState(false);\n const [sortOption, setSortOption] = useState<SortOption>('relevance');\n const [showFilters, setShowFilters] = useState(false);\n\n // Debounce search query - 1.5 seconds for better UX\n const debouncedSearchQuery = useDebounce(searchQuery, 1500);\n\n // Filter options\n const pricingOptions = [\n { value: 'all', label: 'All Prices' },\n { value: 'free', label: 'Free' },\n { value: 'paid', label: 'Paid (One-time)' },\n { value: 'subscription', label: 'Subscription' },\n ];\n\n const ratingOptions = [\n { value: 'any', label: 'Any Rating' },\n { value: '3', label: '3+ Stars' },\n { value: '3.5', label: '3.5+ Stars' },\n { value: '4', label: '4+ Stars' },\n { value: '4.5', label: '4.5+ Stars' },\n ];\n\n const natureOptions = [\n { value: 'all', label: 'All Types' },\n { value: 'digital', label: 'Digital' },\n { value: 'physical', label: 'Physical' },\n ];\n\n const sortOptions = [\n { value: 'relevance', label: 'Relevance' },\n { value: 'rating', label: 'Highest Rated' },\n { value: 'downloads', label: 'Most Downloads' },\n { value: 'newest', label: 'Newest First' },\n { value: 'price-low', label: 'Price: Low to High' },\n { value: 'price-high', label: 'Price: High to Low' },\n { value: 'name-asc', label: 'Name A-Z' },\n ];\n\n // Map UI sort option to GraphQL StoreSortBy enum\n const mapSortToApi = (sort: SortOption): StoreSortBy => {\n const mapping: Record<SortOption, StoreSortBy> = {\n relevance: StoreSortBy.Relevance,\n rating: StoreSortBy.Rating,\n downloads: StoreSortBy.Downloads,\n newest: StoreSortBy.Newest,\n 'price-low': StoreSortBy.PriceLow,\n 'price-high': StoreSortBy.PriceHigh,\n 'name-asc': StoreSortBy.NameAsc,\n };\n return mapping[sort];\n };\n\n // Map UI pricing filter to GraphQL PricingModel enum\n const mapPricingToApi = (pricing: PricingFilter): PricingModel | undefined => {\n if (pricing === 'all') return undefined;\n const mapping: Record<string, PricingModel> = {\n free: PricingModel.Free,\n paid: PricingModel.PaidOnetime,\n subscription: PricingModel.Subscription,\n };\n return mapping[pricing];\n };\n\n // Check if any filter is active (using debounced search for API calls)\n const hasActiveFilters =\n debouncedSearchQuery.trim() !== '' ||\n pricingFilter !== 'all' ||\n ratingFilter !== 'any' ||\n natureFilter !== 'all' ||\n selectedCategory !== 'all' ||\n selectedLicense !== 'all' ||\n featuredOnly ||\n selectedType !== 'all' ||\n sortOption !== 'relevance';\n\n // Check if user is currently typing (search not yet debounced)\n const isSearchPending = searchQuery.trim() !== '' && searchQuery !== debouncedSearchQuery;\n\n const clearAllFilters = () => {\n setSearchQuery('');\n setPricingFilter('all');\n setRatingFilter('any');\n setNatureFilter('all');\n setSelectedCategory('all');\n setSelectedLicense('all');\n setFeaturedOnly(false);\n setSortOption('relevance');\n setSelectedType('all');\n };\n\n // Count active filters (excluding search and sort)\n const activeFilterCount =\n (pricingFilter !== 'all' ? 1 : 0) +\n (ratingFilter !== 'any' ? 1 : 0) +\n (natureFilter !== 'all' ? 1 : 0) +\n (selectedCategory !== 'all' ? 1 : 0) +\n (selectedLicense !== 'all' ? 1 : 0) +\n (featuredOnly ? 1 : 0) +\n (selectedType !== 'all' ? 1 : 0);\n\n // Build BrowseStoreInput from filter states for API call\n const browseStoreInput: BrowseStoreInput = useMemo(() => {\n const input: BrowseStoreInput = {\n sortBy: mapSortToApi(sortOption),\n pagination: { limit: 50 },\n };\n\n // Only add filter if we have active filters\n if (hasActiveFilters) {\n input.filter = {};\n\n // Search query (debounced)\n if (debouncedSearchQuery.trim()) {\n input.filter.search = debouncedSearchQuery.trim();\n }\n\n // Type filter\n if (selectedType !== 'all') {\n input.filter.type = selectedType as BrowseStoreInput['filter'] extends { type?: infer T }\n ? T\n : never;\n }\n\n // Category filter\n if (selectedCategory !== 'all') {\n input.filter.category = selectedCategory;\n }\n\n // Nature filter (digital/physical)\n if (natureFilter !== 'all') {\n input.filter.nature =\n natureFilter === 'digital' ? ProductNature.Digital : ProductNature.Physical;\n }\n\n // Pricing filter\n const pricingModel = mapPricingToApi(pricingFilter);\n if (pricingModel) {\n input.filter.pricingModel = pricingModel;\n }\n\n // Rating filter\n if (ratingFilter !== 'any') {\n input.filter.minRating = parseFloat(ratingFilter);\n }\n\n // Featured filter\n if (featuredOnly) {\n input.filter.featured = true;\n }\n\n // License filter\n if (selectedLicense !== 'all') {\n input.filter.license = selectedLicense;\n }\n }\n\n return input;\n }, [\n debouncedSearchQuery,\n selectedType,\n selectedCategory,\n natureFilter,\n pricingFilter,\n ratingFilter,\n featuredOnly,\n selectedLicense,\n sortOption,\n hasActiveFilters,\n ]);\n\n // Fetch grouped products for homepage (when no filters active)\n const {\n featured,\n mostDownloaded,\n recentlyAdded,\n freeItems,\n loading: homeLoading,\n error: homeError,\n refetch: refetchHome,\n } = useHomeGroupedProducts({ skip: hasActiveFilters });\n\n // Fetch filtered products from API when filters are active\n const {\n products: browseProducts,\n totalCount,\n facets,\n loading: browseLoading,\n error: browseError,\n refetch: refetchBrowse,\n } = useBrowseStoreWithContext(hasActiveFilters ? browseStoreInput : {}, {\n skip: !hasActiveFilters,\n });\n\n // Determine which data to show\n const loading = hasActiveFilters ? browseLoading : homeLoading;\n const error = hasActiveFilters ? browseError : homeError;\n const refetch = hasActiveFilters ? refetchBrowse : refetchHome;\n\n // Products to display when filters are active\n const filteredProducts = hasActiveFilters ? browseProducts : [];\n\n // Emit search event when debounced query resolves. Read totalCount via ref so\n // we don't re-emit when only the count changes.\n const totalCountRef = useRef(totalCount);\n totalCountRef.current = totalCount;\n const busRef = useRef(bus);\n busRef.current = bus;\n useEffect(() => {\n if (!debouncedSearchQuery.trim() || browseLoading) return;\n (busRef.current as unknown as { emit: (name: string, payload: unknown) => void }).emit(\n 'store.marketplace.searched',\n {\n query: debouncedSearchQuery,\n resultCount: totalCountRef.current,\n }\n );\n }, [debouncedSearchQuery, browseLoading]);\n\n const handleProductClick = useCallback(\n (product: StoreProduct) => {\n navigate(`${basePath}/marketplace/product/${product.id}`);\n },\n [navigate, basePath]\n );\n\n const handleCheckout = () => {\n closeCart();\n navigate(`${basePath}/cart`);\n };\n\n // Get all unique products for the homepage \"All Apps\" section\n const allProducts = useMemo(\n () => [\n ...new Map(\n [...featured, ...mostDownloaded, ...recentlyAdded, ...freeItems].map((p) => [p.id, p])\n ).values(),\n ],\n [featured, mostDownloaded, recentlyAdded, freeItems]\n );\n\n // Build dynamic filter options from facets (when available) or from homepage products\n const typeCategories = useMemo(() => {\n // Use facets from API if available\n if (facets?.types && facets.types.length > 0) {\n return [\n { id: 'all', name: 'All Apps', count: totalCount },\n ...facets.types.map((t) => ({\n id: t.value,\n name: t.value.charAt(0) + t.value.slice(1).toLowerCase().replace(/_/g, ' '),\n count: t.count,\n })),\n ];\n }\n // Fallback to homepage products: count each type in a single pass.\n const typeCounts = allProducts.reduce<Map<string, number>>((acc, p) => {\n acc.set(p.type, (acc.get(p.type) ?? 0) + 1);\n return acc;\n }, new Map());\n const typeOptions = Array.from(typeCounts.entries())\n .flatMap(([type, count]) =>\n count > 0\n ? [\n {\n id: type,\n name: type.charAt(0) + type.slice(1).toLowerCase().replace(/_/g, ' '),\n count,\n },\n ]\n : []\n )\n .sort((a, b) => b.count - a.count);\n return [{ id: 'all', name: 'All Apps', count: allProducts.length }, ...typeOptions];\n }, [facets, allProducts, totalCount]);\n\n // Build category options from facets or products\n const categoryOptions = useMemo(() => {\n if (facets?.categories && facets.categories.length > 0) {\n return [\n { value: 'all', label: 'All Categories' },\n ...facets.categories.map((c) => ({\n value: c.value,\n label: c.value,\n })),\n ];\n }\n return [\n { value: 'all', label: 'All Categories' },\n ...Array.from(new Set(allProducts.flatMap((p) => (p.category ? [p.category] : []))))\n .map((cat) => ({\n value: cat as string,\n label: cat as string,\n }))\n .sort((a, b) => a.label.localeCompare(b.label)),\n ];\n }, [facets, allProducts]);\n\n // Build license options from facets or static list\n const licenseOptions = useMemo(() => {\n if (facets?.licenses && facets.licenses.length > 0) {\n return [\n { value: 'all', label: 'All Licenses' },\n ...facets.licenses.map((l) => ({\n value: l.value,\n label: l.value,\n })),\n ];\n }\n return [{ value: 'all', label: 'All Licenses' }];\n }, [facets]);\n\n return (\n <div className=\"flex h-full flex-col\">\n {/* Header */}\n <header className=\"border-b border-border-default bg-bg-surface px-6 py-4\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold text-text-primary\">\n App {t('pages.marketplace.title', { defaultValue: 'Marketplace' })}\n </h1>\n <p className=\"text-sm text-text-muted\">\n {t('pages.marketplace.subtitle', {\n defaultValue: 'Discover apps, workflows, and integrations for your workspace',\n })}\n </p>\n </div>\n <button\n type=\"button\"\n data-tour=\"store-marketplace-cart-button\"\n onClick={() => navigate(`${basePath}/cart`)}\n className=\"cursor-pointer relative flex items-center gap-2 rounded-lg border border-border-default bg-bg-surface px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken\"\n >\n <ShoppingCart className=\"size-5\" />\n {t('pages.marketplace.cart', { defaultValue: 'Cart' })}\n {itemCount > 0 && (\n <span className=\"absolute -right-2 -top-2 flex size-5 items-center justify-center rounded-full bg-action-primary-bg text-xs font-bold text-action-primary-text\">\n {itemCount}\n </span>\n )}\n </button>\n </div>\n\n {/* Search Bar - Live filtering as you type */}\n <div className=\"mt-4\">\n <div className=\"relative\">\n <label htmlFor={searchInputId} className=\"sr-only\">\n {t('pages.marketplace.search.label', { defaultValue: 'Search marketplace products' })}\n </label>\n <Search className=\"absolute left-4 top-1/2 size-5 -translate-y-1/2 text-text-muted\" />\n <input\n id={searchInputId}\n data-tour=\"store-marketplace-search-input\"\n aria-label={t('pages.marketplace.search.label', {\n defaultValue: 'Search marketplace products',\n })}\n type=\"text\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n placeholder={t('pages.marketplace.search.placeholder', {\n defaultValue: 'Search apps, workflows, integrations...',\n })}\n className=\"w-full rounded-xl border border-border-default bg-bg-sunken py-3 pl-12 pr-4 text-text-primary placeholder-text-muted focus:border-action-primary-border focus:bg-bg-surface focus:outline-none focus:ring-2 focus:ring-action-primary-border/20\"\n />\n {searchQuery && (\n <button\n type=\"button\"\n onClick={() => setSearchQuery('')}\n aria-label={t('pages.marketplace.search.clear', { defaultValue: 'Clear search' })}\n className=\"cursor-pointer absolute right-4 top-1/2 -translate-y-1/2 text-text-muted transition-colors hover:text-text-primary\"\n >\n <X className=\"size-4\" aria-hidden=\"true\" />\n </button>\n )}\n </div>\n {/* Search results count / pending indicator */}\n {searchQuery.trim() && (\n <div\n aria-live=\"polite\"\n className=\"mt-2 flex items-center gap-2 text-sm text-text-muted\"\n >\n {isSearchPending || browseLoading ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n <span>\n {t('pages.marketplace.search.searching', { defaultValue: 'Searching...' })}\n </span>\n </>\n ) : (\n <span>\n {totalCount} result{totalCount !== 1 ? 's' : ''} for “{debouncedSearchQuery}\n ”\n </span>\n )}\n </div>\n )}\n </div>\n\n {/* Filter Bar */}\n <div className=\"mt-4 flex flex-wrap items-center gap-3\">\n {/* Filter Toggle Button */}\n <button\n type=\"button\"\n data-tour=\"store-marketplace-filters-button\"\n onClick={() => setShowFilters(!showFilters)}\n className={`cursor-pointer flex items-center gap-2 rounded-lg border px-3 py-2 text-sm font-medium transition-colors ${\n showFilters || activeFilterCount > 0\n ? 'border-action-primary-border bg-action-primary-bg/10 text-text-link'\n : 'border-border-default bg-bg-surface text-text-primary transition-colors hover:bg-bg-sunken'\n }`}\n >\n <SlidersHorizontal className=\"size-4\" />\n {t('pages.marketplace.filters', { defaultValue: 'Filters' })}\n {activeFilterCount > 0 && (\n <span className=\"flex size-5 items-center justify-center rounded-full bg-action-primary-bg text-xs text-action-primary-text\">\n {activeFilterCount}\n </span>\n )}\n </button>\n\n {/* Quick Filter Chips - Always visible */}\n <div\n className=\"flex flex-wrap items-center gap-2\"\n data-tour=\"store-marketplace-quick-filters\"\n >\n <button\n type=\"button\"\n onClick={() => setPricingFilter(pricingFilter === 'free' ? 'all' : 'free')}\n className={`cursor-pointer flex items-center gap-1.5 rounded-full px-3 py-1.5 text-sm font-medium transition-colors ${\n pricingFilter === 'free'\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-sunken text-text-primary transition-colors hover:bg-bg-surface'\n }`}\n >\n <Gift className=\"size-3.5\" />\n Free\n </button>\n <button\n type=\"button\"\n onClick={() => setRatingFilter(ratingFilter === '4' ? 'any' : '4')}\n className={`cursor-pointer flex items-center gap-1.5 rounded-full px-3 py-1.5 text-sm font-medium transition-colors ${\n ratingFilter === '4'\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-sunken text-text-primary transition-colors hover:bg-bg-surface'\n }`}\n >\n <Star className=\"size-3.5\" />\n 4+ Stars\n </button>\n <button\n type=\"button\"\n onClick={() => setFeaturedOnly(!featuredOnly)}\n className={`cursor-pointer flex items-center gap-1.5 rounded-full px-3 py-1.5 text-sm font-medium transition-colors ${\n featuredOnly\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-sunken text-text-primary transition-colors hover:bg-bg-surface'\n }`}\n >\n <Sparkles className=\"size-3.5\" />\n Featured\n </button>\n </div>\n\n {/* Clear Filters */}\n {hasActiveFilters && (\n <button\n type=\"button\"\n onClick={clearAllFilters}\n className=\"cursor-pointer flex items-center gap-1 text-sm text-text-muted transition-colors hover:text-text-primary\"\n >\n <X className=\"size-4\" aria-hidden=\"true\" />\n Clear all\n </button>\n )}\n\n {/* Sort Dropdown - Right aligned */}\n <div className=\"ml-auto\" data-tour=\"store-marketplace-section-sort\">\n <FilterDropdown\n label=\"Sort\"\n value={sortOption}\n options={sortOptions}\n onChange={(value) => setSortOption(value as SortOption)}\n />\n </div>\n </div>\n\n {/* Expanded Filters Panel */}\n {showFilters && (\n <div className=\"mt-4 rounded-lg border border-border-default bg-bg-surface p-4\">\n <div className=\"flex flex-wrap items-start gap-6\">\n {/* Pricing Filter */}\n <div className=\"flex flex-col gap-2\">\n <span className=\"text-xs font-medium uppercase tracking-wider text-text-muted\">\n Pricing\n </span>\n <FilterDropdown\n label=\"Price\"\n value={pricingFilter}\n options={pricingOptions}\n onChange={(value) => setPricingFilter(value as PricingFilter)}\n />\n </div>\n\n {/* Rating Filter */}\n <div className=\"flex flex-col gap-2\">\n <span className=\"text-xs font-medium uppercase tracking-wider text-text-muted\">\n Min Rating\n </span>\n <FilterDropdown\n label=\"Rating\"\n value={ratingFilter}\n options={ratingOptions}\n onChange={(value) => setRatingFilter(value as RatingFilter)}\n />\n </div>\n\n {/* Category Filter */}\n {categoryOptions.length > 1 && (\n <div className=\"flex flex-col gap-2\">\n <span className=\"text-xs font-medium uppercase tracking-wider text-text-muted\">\n Category\n </span>\n <FilterDropdown\n label=\"Category\"\n value={selectedCategory}\n options={categoryOptions}\n onChange={setSelectedCategory}\n />\n </div>\n )}\n\n {/* Nature Filter (Digital/Physical) */}\n <div className=\"flex flex-col gap-2\">\n <span className=\"text-xs font-medium uppercase tracking-wider text-text-muted\">\n Nature\n </span>\n <FilterDropdown\n label=\"Nature\"\n value={natureFilter}\n options={natureOptions}\n onChange={(value) => setNatureFilter(value as NatureFilter)}\n />\n </div>\n\n {/* License Filter */}\n {licenseOptions.length > 1 && (\n <div className=\"flex flex-col gap-2\">\n <span className=\"text-xs font-medium uppercase tracking-wider text-text-muted\">\n License\n </span>\n <FilterDropdown\n label=\"License\"\n value={selectedLicense}\n options={licenseOptions}\n onChange={setSelectedLicense}\n />\n </div>\n )}\n </div>\n\n {/* Active Filters Summary */}\n {activeFilterCount > 0 && (\n <div className=\"mt-4 flex flex-wrap items-center gap-2 border-t border-border-default pt-4\">\n <span className=\"text-xs font-medium text-text-muted\">Active filters:</span>\n {selectedType !== 'all' && (\n <button\n type=\"button\"\n onClick={() => setSelectedType('all')}\n className=\"inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-action-primary-border bg-action-primary-bg/5 px-3 py-1.5 text-xs font-medium text-text-link shadow-sm transition-colors hover:bg-action-primary-bg/15\"\n >\n <span className=\"text-text-muted\">Type:</span> {selectedType}\n <X className=\"size-3\" aria-hidden=\"true\" />\n </button>\n )}\n {pricingFilter !== 'all' && (\n <button\n type=\"button\"\n onClick={() => setPricingFilter('all')}\n className=\"inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-action-primary-border bg-action-primary-bg/5 px-3 py-1.5 text-xs font-medium text-text-link shadow-sm transition-colors hover:bg-action-primary-bg/15\"\n >\n <span className=\"text-text-muted\">Price:</span>{' '}\n {pricingOptions.find((o) => o.value === pricingFilter)?.label}\n <X className=\"size-3\" aria-hidden=\"true\" />\n </button>\n )}\n {ratingFilter !== 'any' && (\n <button\n type=\"button\"\n onClick={() => setRatingFilter('any')}\n className=\"inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-action-primary-border bg-action-primary-bg/5 px-3 py-1.5 text-xs font-medium text-text-link shadow-sm transition-colors hover:bg-action-primary-bg/15\"\n >\n <span className=\"text-text-muted\">Rating:</span>{' '}\n {ratingOptions.find((o) => o.value === ratingFilter)?.label}\n <X className=\"size-3\" aria-hidden=\"true\" />\n </button>\n )}\n {selectedCategory !== 'all' && (\n <button\n type=\"button\"\n onClick={() => setSelectedCategory('all')}\n className=\"inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-action-primary-border bg-action-primary-bg/5 px-3 py-1.5 text-xs font-medium text-text-link shadow-sm transition-colors hover:bg-action-primary-bg/15\"\n >\n <span className=\"text-text-muted\">Category:</span> {selectedCategory}\n <X className=\"size-3\" aria-hidden=\"true\" />\n </button>\n )}\n {natureFilter !== 'all' && (\n <button\n type=\"button\"\n onClick={() => setNatureFilter('all')}\n className=\"inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-action-primary-border bg-action-primary-bg/5 px-3 py-1.5 text-xs font-medium text-text-link shadow-sm transition-colors hover:bg-action-primary-bg/15\"\n >\n <span className=\"text-text-muted\">Nature:</span>{' '}\n {natureOptions.find((o) => o.value === natureFilter)?.label}\n <X className=\"size-3\" aria-hidden=\"true\" />\n </button>\n )}\n {selectedLicense !== 'all' && (\n <button\n type=\"button\"\n onClick={() => setSelectedLicense('all')}\n className=\"inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-action-primary-border bg-action-primary-bg/5 px-3 py-1.5 text-xs font-medium text-text-link shadow-sm transition-colors hover:bg-action-primary-bg/15\"\n >\n <span className=\"text-text-muted\">License:</span>{' '}\n {licenseOptions.find((o) => o.value === selectedLicense)?.label}\n <X className=\"size-3\" aria-hidden=\"true\" />\n </button>\n )}\n {featuredOnly && (\n <button\n type=\"button\"\n onClick={() => setFeaturedOnly(false)}\n className=\"inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-action-primary-border bg-action-primary-bg/5 px-3 py-1.5 text-xs font-medium text-text-link shadow-sm transition-colors hover:bg-action-primary-bg/15\"\n >\n <Sparkles className=\"size-3\" />\n Featured Only\n <X className=\"size-3\" aria-hidden=\"true\" />\n </button>\n )}\n </div>\n )}\n </div>\n )}\n </header>\n\n {/* Main Content */}\n <main className=\"flex-1 overflow-y-auto\">\n <div className=\"mx-auto max-w-7xl space-y-8 p-6\">\n {/* Error State */}\n {error && (\n <div\n role=\"alert\"\n className=\"flex flex-col items-center justify-center rounded-xl border border-status-error-border bg-status-error-bg-subtle p-8 text-center\"\n >\n <AlertCircle className=\"mb-4 size-12 text-status-error-text\" />\n <h3 className=\"mb-2 text-lg font-semibold text-status-error-text-emphasis\">\n Failed to load marketplace\n </h3>\n <p className=\"mb-4 text-sm text-status-error-text\">\n {error.message || 'An error occurred while fetching products'}\n </p>\n <button\n type=\"button\"\n onClick={() => refetch()}\n className=\"cursor-pointer rounded-lg bg-status-error-bg px-4 py-2 text-sm font-medium text-status-error-text transition-colors hover:bg-status-error-bg-emphasis\"\n >\n Try Again\n </button>\n </div>\n )}\n\n {/* Loading State */}\n {loading && !error && <MarketplacePageSkeleton />}\n\n {/* Content - Only show when data is loaded */}\n {!loading && !error && (\n <>\n {/* Hero Section - Featured Products (only when no filters) */}\n {!hasActiveFilters && selectedType === 'all' && featured.length > 0 && (\n <HeroSection\n dataTour=\"store-marketplace-hero-section\"\n featuredProducts={featured}\n onProductClick={handleProductClick}\n />\n )}\n\n {/* Type Filter Categories */}\n {typeCategories.length > 1 && (\n <div>\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">Browse by Type</h2>\n <div\n className=\"flex flex-wrap gap-2\"\n data-tour=\"store-marketplace-type-categories\"\n >\n {typeCategories.map((category) => (\n <CategoryChip\n key={category.id}\n typeId={category.id}\n name={category.name}\n count={category.count}\n active={selectedType === category.id}\n onClick={() => setSelectedType(category.id)}\n />\n ))}\n </div>\n </div>\n )}\n\n {/* Show Filtered Results when filters are active */}\n {hasActiveFilters && (\n <section>\n <SectionHeader\n icon={Filter}\n title={debouncedSearchQuery ? `Search Results` : 'Filtered Results'}\n subtitle={`${totalCount} app${totalCount !== 1 ? 's' : ''} found`}\n />\n {filteredProducts.length > 0 ? (\n <div\n className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\"\n data-tour=\"store-marketplace-product-grid\"\n >\n {filteredProducts.map((product) => (\n <AppCard\n key={product.id}\n product={product}\n onClick={() => handleProductClick(product)}\n />\n ))}\n </div>\n ) : (\n <div className=\"flex flex-col items-center justify-center rounded-xl border border-border-default bg-bg-surface p-8 text-center\">\n <Filter className=\"mb-4 size-12 text-text-muted\" />\n <h3 className=\"mb-2 text-lg font-semibold text-text-primary\">\n No apps match your filters\n </h3>\n <p className=\"mb-4 text-sm text-text-muted\">\n Try adjusting your filter criteria or clearing filters to see more results.\n </p>\n <button\n type=\"button\"\n onClick={clearAllFilters}\n className=\"cursor-pointer rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-opacity hover:opacity-90\"\n >\n Clear All Filters\n </button>\n </div>\n )}\n </section>\n )}\n\n {/* Show grouped sections only when no filters are active */}\n {!hasActiveFilters && selectedType === 'all' && (\n <>\n {/* Most Downloaded / Trending Apps */}\n {mostDownloaded.length > 0 && (\n <section>\n <SectionHeader\n icon={TrendingUp}\n title=\"Most Downloaded\"\n subtitle=\"Top picks by our community\"\n />\n <div\n className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\"\n data-tour=\"store-marketplace-most-downloaded\"\n >\n {mostDownloaded.slice(0, 6).map((product) => (\n <AppCard\n key={product.id}\n product={product}\n onClick={() => handleProductClick(product)}\n />\n ))}\n </div>\n </section>\n )}\n\n {/* Recently Added / New Releases */}\n {recentlyAdded.length > 0 && (\n <section>\n <SectionHeader\n icon={Clock}\n title=\"New Releases\"\n subtitle=\"Recently published apps\"\n />\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {recentlyAdded.slice(0, 6).map((product) => (\n <AppCard\n key={product.id}\n product={product}\n onClick={() => handleProductClick(product)}\n />\n ))}\n </div>\n </section>\n )}\n\n {/* Free Items */}\n {freeItems.length > 0 && (\n <section>\n <SectionHeader\n icon={Gift}\n title=\"Free Apps\"\n subtitle=\"No cost, full functionality\"\n />\n <div className=\"grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-6\">\n {freeItems.slice(0, 6).map((product) => (\n <AppCard\n key={product.id}\n product={product}\n onClick={() => handleProductClick(product)}\n variant=\"compact\"\n />\n ))}\n </div>\n </section>\n )}\n\n {/* All Apps */}\n {allProducts.length > 0 && (\n <section>\n <SectionHeader\n icon={Box}\n title=\"All Apps\"\n subtitle={`${allProducts.length} apps available`}\n />\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n {allProducts.map((product) => (\n <AppCard\n key={product.id}\n product={product}\n onClick={() => handleProductClick(product)}\n />\n ))}\n </div>\n </section>\n )}\n </>\n )}\n\n {/* Empty State - No products at all */}\n {allProducts.length === 0 && (\n <div className=\"flex flex-col items-center justify-center rounded-xl border border-border-default bg-bg-surface p-12 text-center\">\n <Box className=\"mb-4 size-16 text-text-muted\" />\n <h3 className=\"mb-2 text-xl font-semibold text-text-primary\">\n No apps available yet\n </h3>\n <p className=\"max-w-md text-text-muted\">\n The marketplace is empty. Check back soon for new apps, workflows, and\n integrations.\n </p>\n </div>\n )}\n </>\n )}\n </div>\n </main>\n\n {/* Cart Drawer */}\n <CartDrawer\n isOpen={cartOpen}\n onClose={closeCart}\n onCheckout={handleCheckout}\n cartItems={cartItems}\n itemCount={itemCount}\n subtotal={subtotal}\n tax={tax}\n total={total}\n updateQuantity={updateQuantity}\n removeProduct={removeProduct}\n />\n </div>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MarketplaceHomePage.js","names":[],"sources":["../../src/pages/MarketplaceHomePage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useState, useCallback, useMemo, useId, useEffect, useRef } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n Search,\n Star,\n Download,\n ChevronRight,\n ChevronDown,\n Sparkles,\n TrendingUp,\n Clock,\n Bot,\n Brain,\n LayoutDashboard,\n GitBranch,\n Box,\n Puzzle,\n ShoppingCart,\n X,\n AlertCircle,\n Gift,\n Filter,\n SlidersHorizontal,\n Loader2,\n FileCode2,\n Database,\n type LucideIcon,\n} from 'lucide-react';\nimport { useDebounce } from '@burdenoff/fe-libs/shared/hooks';\nimport { useEventBus } from '@burdenoff/fe-libs/shared/events';\nimport { useStore } from '../providers/StoreProvider';\nimport { useCart } from '../hooks/useCart';\nimport { CartDrawer } from '../components/cart/CartDrawer';\nimport {\n useHomeGroupedProducts,\n useBrowseStoreWithContext,\n type StoreProduct,\n} from '../hooks/useStoreGraphQL';\nimport type { BrowseStoreInput } from '../generated/global-types';\nimport { StoreSortBy, PricingModel, ProductNature } from '../generated/global-types';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\n// ========================================\n// Helper Types and Functions\n// ========================================\n\ntype ProductTypeKey =\n | 'BOTAPP'\n | 'AGENT'\n | 'CONSOLE'\n | 'WORKFLOW'\n | 'NODE'\n | 'WIDGET'\n | 'VIBEMODULE'\n | 'DASHBOARD'\n | 'PARSER'\n | 'DATASINK'\n | 'APP'\n | 'TEMPLATE'\n | 'INTEGRATION'\n | 'EXTENSION'\n | 'THEME'\n | 'PLUGIN'\n | 'COMPONENT'\n | string;\n\nconst formatDownloads = (count: number): string => {\n if (count >= 1000000) return `${(count / 1000000).toFixed(1)}M`;\n if (count >= 1000) return `${(count / 1000).toFixed(1)}K`;\n return count.toString();\n};\n\nconst getPriceDisplay = (product: StoreProduct): string => {\n if (product.pricingModel === 'FREE') return 'Free';\n if (product.price === 0) return 'Free';\n return `$${product.price}`;\n};\n\nconst getProductColor = (type: ProductTypeKey): string => {\n const colors: Record<string, string> = {\n BOTAPP: 'var(--color-accent-blue)',\n AGENT: 'var(--color-accent-purple)',\n CONSOLE: 'var(--color-accent-teal)',\n WORKFLOW: 'var(--color-status-warning-bg)',\n NODE: 'var(--color-status-error-bg)',\n WIDGET: 'var(--color-accent-purple)',\n VIBEMODULE: 'var(--color-accent-blue)',\n DASHBOARD: 'var(--color-accent-blue)',\n PARSER: 'var(--color-status-warning-bg)',\n DATASINK: 'var(--color-status-success-bg)',\n APP: 'var(--color-accent-indigo)',\n TEMPLATE: 'var(--color-accent-teal)',\n INTEGRATION: 'var(--color-status-warning-bg)',\n EXTENSION: 'var(--color-accent-purple)',\n THEME: 'var(--color-accent-purple)',\n PLUGIN: 'var(--color-status-success-bg)',\n COMPONENT: 'var(--color-accent-blue)',\n };\n return colors[type] || 'var(--color-text-muted)';\n};\n\n// Helper to get translucent background color from a token\nconst getProductBgColor = (type: ProductTypeKey): string => {\n const color = getProductColor(type);\n return `color-mix(in srgb, ${color}, transparent 85%)`;\n};\n\n// Component wrapper to render type icons\ninterface ProductTypeIconProps {\n type: ProductTypeKey;\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst TYPE_ICONS: Record<string, LucideIcon> = {\n BOTAPP: Bot,\n AGENT: Brain,\n CONSOLE: LayoutDashboard,\n WORKFLOW: GitBranch,\n NODE: Box,\n WIDGET: Puzzle,\n VIBEMODULE: Puzzle,\n DASHBOARD: LayoutDashboard,\n PARSER: FileCode2,\n DATASINK: Database,\n APP: Box,\n TEMPLATE: LayoutDashboard,\n INTEGRATION: GitBranch,\n EXTENSION: Puzzle,\n THEME: Puzzle,\n PLUGIN: Puzzle,\n COMPONENT: Box,\n};\n\nconst ProductTypeIcon: FC<ProductTypeIconProps> = ({ type, className, style }) => {\n const IconComponent = TYPE_ICONS[type] || Box;\n return <IconComponent className={className} style={style} />;\n};\n\n// ========================================\n// App Card Component\n// ========================================\n\ninterface AppCardProps {\n product: StoreProduct;\n onClick: () => void;\n variant?: 'default' | 'compact' | 'featured';\n}\n\nconst AppCard: FC<AppCardProps> = ({ product, onClick, variant = 'default' }) => {\n const productColor = getProductColor(product.type);\n\n if (variant === 'featured') {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className=\"group relative flex size-full cursor-pointer flex-col overflow-hidden rounded-2xl border border-border-default bg-gradient-to-br from-bg-surface to-bg-sunken p-6 text-left transition-all hover:border-action-primary-border hover:shadow-lg\"\n >\n {product.featured && (\n <div className=\"absolute right-4 top-4 flex items-center gap-1 rounded-full bg-status-warning-bg-subtle px-2 py-1 text-xs font-medium text-status-warning-text\">\n <Sparkles className=\"size-3\" />\n Featured\n </div>\n )}\n <div className=\"flex items-start gap-4\">\n <div\n className=\"flex size-16 flex-shrink-0 items-center justify-center rounded-2xl\"\n style={{ backgroundColor: getProductBgColor(product.type) }}\n >\n {product.icon ? (\n <img\n src={product.icon}\n alt={product.name}\n className=\"size-10 rounded-lg object-cover\"\n />\n ) : (\n <ProductTypeIcon\n type={product.type}\n className=\"size-10\"\n style={{ color: productColor }}\n />\n )}\n </div>\n <div className=\"flex-1 overflow-hidden\">\n <h3 className=\"truncate text-lg font-semibold text-text-primary group-hover:text-text-link\">\n {product.name}\n </h3>\n <p className=\"flex items-center gap-2 text-sm text-text-muted\">\n <ProductTypeIcon type={product.type} className=\"size-3.5\" />\n {product.category || product.type}\n </p>\n </div>\n </div>\n <p className=\"mt-4 line-clamp-2 flex-1 text-sm text-text-muted\">\n {product.description || 'No description available'}\n </p>\n <div className=\"mt-4 flex items-center justify-between border-t border-border-default pt-4\">\n <div className=\"flex items-center gap-3\">\n <span className=\"flex items-center gap-1 text-sm text-text-muted\">\n <Star className=\"size-4 fill-current text-status-warning-text\" />\n {(product.rating ?? 0).toFixed(1)}\n </span>\n <span className=\"flex items-center gap-1 text-sm text-text-muted\">\n <Download className=\"size-4\" />\n {formatDownloads(product.downloads)}\n </span>\n </div>\n <span className=\"rounded-full bg-action-primary-bg/10 px-3 py-1 text-sm font-medium text-text-link\">\n {getPriceDisplay(product)}\n </span>\n </div>\n </button>\n );\n }\n\n if (variant === 'compact') {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className=\"group flex cursor-pointer items-center gap-3 rounded-xl border border-transparent p-3 text-left transition-all hover:border-border-default hover:bg-bg-surface\"\n >\n <div\n className=\"flex size-12 flex-shrink-0 items-center justify-center rounded-xl\"\n style={{ backgroundColor: getProductBgColor(product.type) }}\n >\n {product.icon ? (\n <img src={product.icon} alt={product.name} className=\"size-8 rounded-lg object-cover\" />\n ) : (\n <ProductTypeIcon\n type={product.type}\n className=\"size-8\"\n style={{ color: productColor }}\n />\n )}\n </div>\n <div className=\"flex-1 overflow-hidden\">\n <h4 className=\"truncate font-medium text-text-primary group-hover:text-text-link\">\n {product.name}\n </h4>\n <p className=\"truncate text-xs text-text-muted\">\n {product.category || product.type} · {(product.rating ?? 0).toFixed(1)} ★\n </p>\n </div>\n <span className=\"text-xs font-medium text-text-muted\">{getPriceDisplay(product)}</span>\n </button>\n );\n }\n\n // Default variant\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className=\"group flex cursor-pointer flex-col overflow-hidden rounded-xl border border-border-default bg-bg-surface p-4 text-left transition-all hover:border-action-primary-border hover:shadow-md\"\n >\n <div className=\"flex items-start gap-3\">\n <div\n className=\"flex size-14 flex-shrink-0 items-center justify-center rounded-xl\"\n style={{ backgroundColor: getProductBgColor(product.type) }}\n >\n {product.icon ? (\n <img src={product.icon} alt={product.name} className=\"size-9 rounded-lg object-cover\" />\n ) : (\n <ProductTypeIcon\n type={product.type}\n className=\"size-9\"\n style={{ color: productColor }}\n />\n )}\n </div>\n <div className=\"flex-1 overflow-hidden\">\n <h4 className=\"truncate font-semibold text-text-primary group-hover:text-text-link\">\n {product.name}\n </h4>\n <p className=\"flex items-center gap-1.5 text-xs text-text-muted\">\n <ProductTypeIcon type={product.type} className=\"size-3\" />\n {product.category || product.type}\n </p>\n </div>\n </div>\n <p className=\"mt-3 line-clamp-2 text-sm text-text-muted\">\n {product.description || 'No description available'}\n </p>\n <div className=\"mt-3 flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <span className=\"flex items-center gap-0.5 text-xs text-text-muted\">\n <Star className=\"size-3.5 fill-current text-status-warning-text\" />\n {(product.rating ?? 0).toFixed(1)}\n </span>\n <span className=\"text-xs text-text-muted\">·</span>\n <span className=\"text-xs text-text-muted\">\n {formatDownloads(product.downloads)} downloads\n </span>\n </div>\n <span className=\"text-xs font-semibold text-text-link\">{getPriceDisplay(product)}</span>\n </div>\n </button>\n );\n};\n\n// ========================================\n// Section Header Component\n// ========================================\n\ninterface SectionHeaderProps {\n icon: typeof Sparkles;\n title: string;\n subtitle?: string;\n onViewAll?: () => void;\n}\n\nconst SectionHeader: FC<SectionHeaderProps> = ({ icon: Icon, title, subtitle, onViewAll }) => (\n <div className=\"mb-4 flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex size-10 items-center justify-center rounded-xl bg-action-primary-bg/10\">\n <Icon className=\"size-5 text-text-link\" />\n </div>\n <div>\n <h2 className=\"text-lg font-semibold text-text-primary\">{title}</h2>\n {subtitle && <p className=\"text-sm text-text-muted\">{subtitle}</p>}\n </div>\n </div>\n {onViewAll && (\n <button\n type=\"button\"\n onClick={onViewAll}\n className=\"cursor-pointer flex items-center gap-1 text-sm font-medium text-text-link hover:underline\"\n >\n View all\n <ChevronRight className=\"size-4\" />\n </button>\n )}\n </div>\n);\n\n// ========================================\n// Category Chip Component\n// ========================================\n\ninterface CategoryChipProps {\n typeId: ProductTypeKey;\n name: string;\n count: number;\n active?: boolean;\n onClick: () => void;\n}\n\nconst CategoryChip: FC<CategoryChipProps> = ({ typeId, name, count, active, onClick }) => (\n <button\n type=\"button\"\n onClick={onClick}\n className={`flex cursor-pointer items-center gap-2 rounded-full px-4 py-2 text-sm font-medium transition-all ${\n active\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-surface text-text-primary hover:bg-bg-sunken'\n }`}\n >\n <ProductTypeIcon type={typeId} className=\"size-4\" />\n {name}\n <span\n className={`rounded-full px-1.5 py-0.5 text-xs ${active ? 'bg-bg-surface/20' : 'bg-bg-sunken'}`}\n >\n {count}\n </span>\n </button>\n);\n\n// ========================================\n// Hero Section Component\n// ========================================\n\ninterface HeroSectionProps {\n featuredProducts: StoreProduct[];\n onProductClick: (product: StoreProduct) => void;\n /** Optional tour anchor placed on the hero root (avoids an extra wrapper div). */\n dataTour?: string;\n}\n\nconst HeroSection: FC<HeroSectionProps> = ({ featuredProducts, onProductClick, dataTour }) => {\n const [activeIndex, setActiveIndex] = useState(0);\n const heroProduct = featuredProducts[activeIndex] || featuredProducts[0];\n\n if (!heroProduct) return null;\n\n const productColor = getProductColor(heroProduct.type);\n\n return (\n <div\n data-tour={dataTour}\n className=\"relative overflow-hidden rounded-2xl bg-gradient-to-r from-bg-surface via-bg-sunken to-bg-surface p-8\"\n >\n <div\n className=\"absolute inset-0 opacity-10\"\n style={{\n background: `linear-gradient(135deg, ${productColor} 0%, transparent 50%)`,\n }}\n />\n <div className=\"relative z-10 flex items-center gap-8\">\n <div className=\"flex-1\">\n <div className=\"mb-4 flex items-center gap-2\">\n <span className=\"flex items-center gap-1 rounded-full bg-status-warning-bg-subtle px-3 py-1 text-xs font-semibold text-status-warning-text\">\n <Sparkles className=\"size-3\" />\n Featured App\n </span>\n <span className=\"rounded-full bg-action-primary-bg/10 px-3 py-1 text-xs font-medium text-text-link\">\n {heroProduct.category || heroProduct.type}\n </span>\n </div>\n <h1 className=\"mb-3 text-3xl font-bold text-text-primary\">{heroProduct.name}</h1>\n <p className=\"mb-6 max-w-xl text-text-muted\">\n {heroProduct.description || 'No description available'}\n </p>\n <div className=\"mb-6 flex items-center gap-4\">\n <span className=\"flex items-center gap-1 text-sm\">\n <Star className=\"size-5 fill-current text-status-warning-text\" />\n <span className=\"font-semibold text-text-primary\">\n {(heroProduct.rating ?? 0).toFixed(1)}\n </span>\n <span className=\"text-text-muted\">({heroProduct.reviewCount} reviews)</span>\n </span>\n <span className=\"flex items-center gap-1 text-sm text-text-muted\">\n <Download className=\"size-4\" />\n {heroProduct.downloads.toLocaleString()} downloads\n </span>\n </div>\n <button\n type=\"button\"\n onClick={() => onProductClick(heroProduct)}\n className=\"cursor-pointer rounded-lg bg-action-primary-bg px-6 py-3 font-semibold text-action-primary-text transition-opacity hover:opacity-90\"\n >\n View Details\n </button>\n </div>\n <div className=\"hidden flex-shrink-0 lg:block\">\n <div\n className=\"flex size-48 items-center justify-center rounded-3xl shadow-lg\"\n style={{ backgroundColor: getProductBgColor(heroProduct.type) }}\n >\n {heroProduct.icon ? (\n <img\n src={heroProduct.icon}\n alt={heroProduct.name}\n className=\"size-32 rounded-2xl object-cover\"\n />\n ) : (\n <ProductTypeIcon\n type={heroProduct.type}\n className=\"size-32\"\n style={{ color: productColor }}\n />\n )}\n </div>\n </div>\n </div>\n {/* Featured App Selector */}\n {featuredProducts.length > 1 && (\n <div className=\"relative z-10 mt-6 flex gap-2\">\n {featuredProducts.map((product, index) => (\n <button\n type=\"button\"\n key={product.id}\n onClick={() => setActiveIndex(index)}\n className={`h-2 w-8 rounded-full transition-all ${\n index === activeIndex\n ? 'bg-action-primary-bg'\n : 'bg-border-default hover:bg-action-primary-border'\n }`}\n aria-label={`View ${product.name}`}\n />\n ))}\n </div>\n )}\n </div>\n );\n};\n\n// ========================================\n// Loading Skeleton Components\n// ========================================\n\nconst ProductCardSkeleton: FC<{ variant?: 'default' | 'compact' | 'featured' }> = ({\n variant = 'default',\n}) => {\n if (variant === 'featured') {\n return (\n <div className=\"h-full animate-pulse rounded-2xl border border-border-default bg-bg-surface p-6\">\n <div className=\"flex items-start gap-4\">\n <div className=\"size-16 rounded-2xl bg-bg-sunken\" />\n <div className=\"flex-1 space-y-2\">\n <div className=\"h-5 w-3/4 rounded bg-bg-sunken\" />\n <div className=\"h-4 w-1/2 rounded bg-bg-sunken\" />\n </div>\n </div>\n <div className=\"mt-4 space-y-2\">\n <div className=\"h-4 w-full rounded bg-bg-sunken\" />\n <div className=\"h-4 w-2/3 rounded bg-bg-sunken\" />\n </div>\n </div>\n );\n }\n\n if (variant === 'compact') {\n return (\n <div className=\"flex animate-pulse items-center gap-3 p-3\">\n <div className=\"size-12 rounded-xl bg-bg-sunken\" />\n <div className=\"flex-1 space-y-2\">\n <div className=\"h-4 w-3/4 rounded bg-bg-sunken\" />\n <div className=\"h-3 w-1/2 rounded bg-bg-sunken\" />\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"animate-pulse rounded-xl border border-border-default bg-bg-surface p-4\">\n <div className=\"flex items-start gap-3\">\n <div className=\"size-14 rounded-xl bg-bg-sunken\" />\n <div className=\"flex-1 space-y-2\">\n <div className=\"h-4 w-3/4 rounded bg-bg-sunken\" />\n <div className=\"h-3 w-1/2 rounded bg-bg-sunken\" />\n </div>\n </div>\n <div className=\"mt-3 space-y-2\">\n <div className=\"h-3 w-full rounded bg-bg-sunken\" />\n <div className=\"h-3 w-2/3 rounded bg-bg-sunken\" />\n </div>\n </div>\n );\n};\n\n// Hero Section Skeleton\nconst HeroSkeleton: FC = () => (\n <div className=\"animate-pulse rounded-2xl bg-gradient-to-r from-bg-surface via-bg-sunken to-bg-surface p-8\">\n <div className=\"flex items-center gap-8\">\n <div className=\"flex-1 space-y-4\">\n <div className=\"flex gap-2\">\n <div className=\"h-6 w-24 rounded-full bg-bg-sunken\" />\n <div className=\"h-6 w-20 rounded-full bg-bg-sunken\" />\n </div>\n <div className=\"h-9 w-3/4 rounded bg-bg-sunken\" />\n <div className=\"space-y-2\">\n <div className=\"h-4 w-full rounded bg-bg-sunken\" />\n <div className=\"h-4 w-5/6 rounded bg-bg-sunken\" />\n </div>\n <div className=\"flex gap-4\">\n <div className=\"h-5 w-24 rounded bg-bg-sunken\" />\n <div className=\"h-5 w-32 rounded bg-bg-sunken\" />\n </div>\n <div className=\"h-12 w-36 rounded-lg bg-bg-sunken\" />\n </div>\n <div className=\"hidden size-48 rounded-3xl bg-bg-sunken lg:block\" />\n </div>\n <div className=\"mt-6 flex gap-2\">\n {[...Array(3)].map((_, i) => (\n <div key={i} className=\"h-2 w-8 rounded-full bg-bg-sunken\" />\n ))}\n </div>\n </div>\n);\n\n// Category Chips Skeleton (Browse by Type)\nconst CHIP_WIDTHS = [100, 120, 90, 110, 130, 95, 115, 105];\n\nconst CategoryChipsSkeleton: FC = () => (\n <div className=\"space-y-4\">\n <div className=\"h-6 w-32 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"flex flex-wrap gap-2\">\n {CHIP_WIDTHS.map((width, i) => (\n <div\n key={i}\n className=\"h-9 animate-pulse rounded-full bg-bg-sunken\"\n style={{ width: `${width}px` }}\n />\n ))}\n </div>\n </div>\n);\n\n// Section Header Skeleton\nconst SectionHeaderSkeleton: FC = () => (\n <div className=\"mb-4 flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"size-10 animate-pulse rounded-xl bg-bg-sunken\" />\n <div className=\"space-y-1\">\n <div className=\"h-5 w-40 animate-pulse rounded bg-bg-sunken\" />\n <div className=\"h-4 w-32 animate-pulse rounded bg-bg-sunken\" />\n </div>\n </div>\n <div className=\"h-4 w-16 animate-pulse rounded bg-bg-sunken\" />\n </div>\n);\n\n// Full Page Skeleton - shows complete loading state\nconst MarketplacePageSkeleton: FC = () => (\n <div className=\"mx-auto max-w-7xl space-y-8 p-6\">\n {/* Hero Section */}\n <HeroSkeleton />\n\n {/* Browse by Type */}\n <CategoryChipsSkeleton />\n\n {/* Most Downloaded Section */}\n <div>\n <SectionHeaderSkeleton />\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {[...Array(6)].map((_, i) => (\n <ProductCardSkeleton key={i} />\n ))}\n </div>\n </div>\n\n {/* New Releases Section */}\n <div>\n <SectionHeaderSkeleton />\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {[...Array(6)].map((_, i) => (\n <ProductCardSkeleton key={i} />\n ))}\n </div>\n </div>\n\n {/* Free Apps Section */}\n <div>\n <SectionHeaderSkeleton />\n <div className=\"grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-6\">\n {[...Array(6)].map((_, i) => (\n <ProductCardSkeleton key={i} variant=\"compact\" />\n ))}\n </div>\n </div>\n </div>\n);\n\n// ========================================\n// Filter Types\n// ========================================\n\ntype PricingFilter = 'all' | 'free' | 'paid' | 'subscription';\ntype RatingFilter = 'any' | '3' | '3.5' | '4' | '4.5';\ntype NatureFilter = 'all' | 'digital' | 'physical';\ntype SortOption =\n | 'relevance'\n | 'rating'\n | 'downloads'\n | 'newest'\n | 'price-low'\n | 'price-high'\n | 'name-asc';\n\ninterface FilterDropdownProps {\n label: string;\n value: string;\n options: { value: string; label: string }[];\n onChange: (value: string) => void;\n}\n\nconst FilterDropdown: FC<FilterDropdownProps> = ({ label, value, options, onChange }) => {\n const selectId = useId();\n\n return (\n <label\n htmlFor={selectId}\n className=\"relative inline-flex items-center gap-2 rounded-lg border border-border-default bg-bg-surface px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken focus-within:border-action-primary-border focus-within:ring-2 focus-within:ring-action-primary-border/20\"\n >\n <span className=\"sr-only\">{label}</span>\n <span className=\"text-text-muted\">{label}:</span>\n <select\n id={selectId}\n aria-label={label}\n value={value}\n onChange={(event) => onChange(event.target.value)}\n className=\"min-w-[8rem] appearance-none bg-transparent pr-6 text-sm font-medium text-text-primary focus:outline-none\"\n >\n {options.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n <ChevronDown className=\"pointer-events-none absolute right-3 size-4 text-text-muted\" />\n </label>\n );\n};\n\n// ========================================\n// Main Page Component\n// ========================================\n\nexport const MarketplaceHomePage: FC = () => {\n const navigate = useNavigate();\n const { basePath } = useStore();\n const { t } = useI18n();\n const searchInputId = useId();\n const bus = useEventBus();\n const {\n cartOpen,\n closeCart,\n itemCount,\n cartItems,\n subtotal,\n tax,\n total,\n updateQuantity,\n removeProduct,\n } = useCart();\n const [searchQuery, setSearchQuery] = useState('');\n const [selectedType, setSelectedType] = useState<string>('all');\n\n // Filter states\n const [pricingFilter, setPricingFilter] = useState<PricingFilter>('all');\n const [ratingFilter, setRatingFilter] = useState<RatingFilter>('any');\n const [natureFilter, setNatureFilter] = useState<NatureFilter>('all');\n const [selectedCategory, setSelectedCategory] = useState<string>('all');\n const [selectedLicense, setSelectedLicense] = useState<string>('all');\n const [featuredOnly, setFeaturedOnly] = useState(false);\n const [sortOption, setSortOption] = useState<SortOption>('relevance');\n const [showFilters, setShowFilters] = useState(false);\n\n // Debounce search query - 1.5 seconds for better UX\n const debouncedSearchQuery = useDebounce(searchQuery, 1500);\n\n // Filter options\n const pricingOptions = [\n { value: 'all', label: 'All Prices' },\n { value: 'free', label: 'Free' },\n { value: 'paid', label: 'Paid (One-time)' },\n { value: 'subscription', label: 'Subscription' },\n ];\n\n const ratingOptions = [\n { value: 'any', label: 'Any Rating' },\n { value: '3', label: '3+ Stars' },\n { value: '3.5', label: '3.5+ Stars' },\n { value: '4', label: '4+ Stars' },\n { value: '4.5', label: '4.5+ Stars' },\n ];\n\n const natureOptions = [\n { value: 'all', label: 'All Types' },\n { value: 'digital', label: 'Digital' },\n { value: 'physical', label: 'Physical' },\n ];\n\n const sortOptions = [\n { value: 'relevance', label: 'Relevance' },\n { value: 'rating', label: 'Highest Rated' },\n { value: 'downloads', label: 'Most Downloads' },\n { value: 'newest', label: 'Newest First' },\n { value: 'price-low', label: 'Price: Low to High' },\n { value: 'price-high', label: 'Price: High to Low' },\n { value: 'name-asc', label: 'Name A-Z' },\n ];\n\n // Map UI sort option to GraphQL StoreSortBy enum\n const mapSortToApi = (sort: SortOption): StoreSortBy => {\n const mapping: Record<SortOption, StoreSortBy> = {\n relevance: StoreSortBy.Relevance,\n rating: StoreSortBy.Rating,\n downloads: StoreSortBy.Downloads,\n newest: StoreSortBy.Newest,\n 'price-low': StoreSortBy.PriceLow,\n 'price-high': StoreSortBy.PriceHigh,\n 'name-asc': StoreSortBy.NameAsc,\n };\n return mapping[sort];\n };\n\n // Map UI pricing filter to GraphQL PricingModel enum\n const mapPricingToApi = (pricing: PricingFilter): PricingModel | undefined => {\n if (pricing === 'all') return undefined;\n const mapping: Record<string, PricingModel> = {\n free: PricingModel.Free,\n paid: PricingModel.PaidOnetime,\n subscription: PricingModel.Subscription,\n };\n return mapping[pricing];\n };\n\n // Check if any filter is active (using debounced search for API calls)\n const hasActiveFilters =\n debouncedSearchQuery.trim() !== '' ||\n pricingFilter !== 'all' ||\n ratingFilter !== 'any' ||\n natureFilter !== 'all' ||\n selectedCategory !== 'all' ||\n selectedLicense !== 'all' ||\n featuredOnly ||\n selectedType !== 'all' ||\n sortOption !== 'relevance';\n\n // Check if user is currently typing (search not yet debounced)\n const isSearchPending = searchQuery.trim() !== '' && searchQuery !== debouncedSearchQuery;\n\n const clearAllFilters = () => {\n setSearchQuery('');\n setPricingFilter('all');\n setRatingFilter('any');\n setNatureFilter('all');\n setSelectedCategory('all');\n setSelectedLicense('all');\n setFeaturedOnly(false);\n setSortOption('relevance');\n setSelectedType('all');\n };\n\n // Count active filters (excluding search and sort)\n const activeFilterCount =\n (pricingFilter !== 'all' ? 1 : 0) +\n (ratingFilter !== 'any' ? 1 : 0) +\n (natureFilter !== 'all' ? 1 : 0) +\n (selectedCategory !== 'all' ? 1 : 0) +\n (selectedLicense !== 'all' ? 1 : 0) +\n (featuredOnly ? 1 : 0) +\n (selectedType !== 'all' ? 1 : 0);\n\n // Build BrowseStoreInput from filter states for API call\n const browseStoreInput: BrowseStoreInput = useMemo(() => {\n const input: BrowseStoreInput = {\n sortBy: mapSortToApi(sortOption),\n pagination: { limit: 50 },\n };\n\n // Only add filter if we have active filters\n if (hasActiveFilters) {\n input.filter = {};\n\n // Search query (debounced)\n if (debouncedSearchQuery.trim()) {\n input.filter.search = debouncedSearchQuery.trim();\n }\n\n // Type filter\n if (selectedType !== 'all') {\n input.filter.type = selectedType as BrowseStoreInput['filter'] extends { type?: infer T }\n ? T\n : never;\n }\n\n // Category filter\n if (selectedCategory !== 'all') {\n input.filter.category = selectedCategory;\n }\n\n // Nature filter (digital/physical)\n if (natureFilter !== 'all') {\n input.filter.nature =\n natureFilter === 'digital' ? ProductNature.Digital : ProductNature.Physical;\n }\n\n // Pricing filter\n const pricingModel = mapPricingToApi(pricingFilter);\n if (pricingModel) {\n input.filter.pricingModel = pricingModel;\n }\n\n // Rating filter\n if (ratingFilter !== 'any') {\n input.filter.minRating = parseFloat(ratingFilter);\n }\n\n // Featured filter\n if (featuredOnly) {\n input.filter.featured = true;\n }\n\n // License filter\n if (selectedLicense !== 'all') {\n input.filter.license = selectedLicense;\n }\n }\n\n return input;\n }, [\n debouncedSearchQuery,\n selectedType,\n selectedCategory,\n natureFilter,\n pricingFilter,\n ratingFilter,\n featuredOnly,\n selectedLicense,\n sortOption,\n hasActiveFilters,\n ]);\n\n // Fetch grouped products for homepage (when no filters active)\n const {\n featured,\n mostDownloaded,\n recentlyAdded,\n freeItems,\n loading: homeLoading,\n error: homeError,\n refetch: refetchHome,\n } = useHomeGroupedProducts({ skip: hasActiveFilters });\n\n // Fetch filtered products from API when filters are active\n const {\n products: browseProducts,\n totalCount,\n facets,\n loading: browseLoading,\n error: browseError,\n refetch: refetchBrowse,\n } = useBrowseStoreWithContext(hasActiveFilters ? browseStoreInput : {}, {\n skip: !hasActiveFilters,\n });\n\n // Determine which data to show\n const loading = hasActiveFilters ? browseLoading : homeLoading;\n const error = hasActiveFilters ? browseError : homeError;\n const refetch = hasActiveFilters ? refetchBrowse : refetchHome;\n\n // Products to display when filters are active\n const filteredProducts = hasActiveFilters ? browseProducts : [];\n\n // Emit search event when debounced query resolves. Read totalCount via ref so\n // we don't re-emit when only the count changes.\n const totalCountRef = useRef(totalCount);\n totalCountRef.current = totalCount;\n const busRef = useRef(bus);\n busRef.current = bus;\n useEffect(() => {\n if (!debouncedSearchQuery.trim() || browseLoading) return;\n (busRef.current as unknown as { emit: (name: string, payload: unknown) => void }).emit(\n 'store.marketplace.searched',\n {\n query: debouncedSearchQuery,\n resultCount: totalCountRef.current,\n }\n );\n }, [debouncedSearchQuery, browseLoading]);\n\n const handleProductClick = useCallback(\n (product: StoreProduct) => {\n navigate(`${basePath}/marketplace/product/${product.id}`);\n },\n [navigate, basePath]\n );\n\n const handleCheckout = () => {\n closeCart();\n navigate(`${basePath}/cart`);\n };\n\n // Get all unique products for the homepage \"All Apps\" section\n const allProducts = useMemo(\n () => [\n ...new Map(\n [...featured, ...mostDownloaded, ...recentlyAdded, ...freeItems].map((p) => [p.id, p])\n ).values(),\n ],\n [featured, mostDownloaded, recentlyAdded, freeItems]\n );\n\n // Build dynamic filter options from facets (when available) or from homepage products\n const typeCategories = useMemo(() => {\n // Use facets from API if available\n if (facets?.types && facets.types.length > 0) {\n return [\n { id: 'all', name: 'All Apps', count: totalCount },\n ...facets.types.map((t) => ({\n id: t.value,\n name: t.value.charAt(0) + t.value.slice(1).toLowerCase().replace(/_/g, ' '),\n count: t.count,\n })),\n ];\n }\n // Fallback to homepage products: count each type in a single pass.\n const typeCounts = allProducts.reduce<Map<string, number>>((acc, p) => {\n acc.set(p.type, (acc.get(p.type) ?? 0) + 1);\n return acc;\n }, new Map());\n const typeOptions = Array.from(typeCounts.entries())\n .flatMap(([type, count]) =>\n count > 0\n ? [\n {\n id: type,\n name: type.charAt(0) + type.slice(1).toLowerCase().replace(/_/g, ' '),\n count,\n },\n ]\n : []\n )\n .sort((a, b) => b.count - a.count);\n return [{ id: 'all', name: 'All Apps', count: allProducts.length }, ...typeOptions];\n }, [facets, allProducts, totalCount]);\n\n // Build category options from facets or products\n const categoryOptions = useMemo(() => {\n if (facets?.categories && facets.categories.length > 0) {\n return [\n { value: 'all', label: 'All Categories' },\n ...facets.categories.map((c) => ({\n value: c.value,\n label: c.value,\n })),\n ];\n }\n return [\n { value: 'all', label: 'All Categories' },\n ...Array.from(new Set(allProducts.flatMap((p) => (p.category ? [p.category] : []))))\n .map((cat) => ({\n value: cat as string,\n label: cat as string,\n }))\n .sort((a, b) => a.label.localeCompare(b.label)),\n ];\n }, [facets, allProducts]);\n\n // Build license options from facets or static list\n const licenseOptions = useMemo(() => {\n if (facets?.licenses && facets.licenses.length > 0) {\n return [\n { value: 'all', label: 'All Licenses' },\n ...facets.licenses.map((l) => ({\n value: l.value,\n label: l.value,\n })),\n ];\n }\n return [{ value: 'all', label: 'All Licenses' }];\n }, [facets]);\n\n return (\n <div className=\"flex h-full flex-col\">\n {/* Header */}\n <header className=\"border-b border-border-default bg-bg-surface px-6 py-4\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold text-text-primary\">\n App {t('pages.marketplace.title', { defaultValue: 'Marketplace' })}\n </h1>\n <p className=\"text-sm text-text-muted\">\n {t('pages.marketplace.subtitle', {\n defaultValue: 'Discover apps, workflows, and integrations for your workspace',\n })}\n </p>\n </div>\n <button\n type=\"button\"\n data-tour=\"store-marketplace-cart-button\"\n onClick={() => navigate(`${basePath}/cart`)}\n className=\"cursor-pointer relative flex items-center gap-2 rounded-lg border border-border-default bg-bg-surface px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken\"\n >\n <ShoppingCart className=\"size-5\" />\n {t('pages.marketplace.cart', { defaultValue: 'Cart' })}\n {itemCount > 0 && (\n <span className=\"absolute -right-2 -top-2 flex size-5 items-center justify-center rounded-full bg-action-primary-bg text-xs font-bold text-action-primary-text\">\n {itemCount}\n </span>\n )}\n </button>\n </div>\n\n {/* Search Bar - Live filtering as you type */}\n <div className=\"mt-4\">\n <div className=\"relative\">\n <label htmlFor={searchInputId} className=\"sr-only\">\n {t('pages.marketplace.search.label', { defaultValue: 'Search marketplace products' })}\n </label>\n <Search className=\"absolute left-4 top-1/2 size-5 -translate-y-1/2 text-text-muted\" />\n <input\n id={searchInputId}\n data-tour=\"store-marketplace-search-input\"\n aria-label={t('pages.marketplace.search.label', {\n defaultValue: 'Search marketplace products',\n })}\n type=\"text\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n placeholder={t('pages.marketplace.search.placeholder', {\n defaultValue: 'Search apps, workflows, integrations...',\n })}\n className=\"w-full rounded-xl border border-border-default bg-bg-sunken py-3 pl-12 pr-4 text-text-primary placeholder-text-muted focus:border-action-primary-border focus:bg-bg-surface focus:outline-none focus:ring-2 focus:ring-action-primary-border/20\"\n />\n {searchQuery && (\n <button\n type=\"button\"\n onClick={() => setSearchQuery('')}\n aria-label={t('pages.marketplace.search.clear', { defaultValue: 'Clear search' })}\n className=\"cursor-pointer absolute right-4 top-1/2 -translate-y-1/2 text-text-muted transition-colors hover:text-text-primary\"\n >\n <X className=\"size-4\" aria-hidden=\"true\" />\n </button>\n )}\n </div>\n {/* Search results count / pending indicator */}\n {searchQuery.trim() && (\n <div\n aria-live=\"polite\"\n className=\"mt-2 flex items-center gap-2 text-sm text-text-muted\"\n >\n {isSearchPending || browseLoading ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n <span>\n {t('pages.marketplace.search.searching', { defaultValue: 'Searching...' })}\n </span>\n </>\n ) : (\n <span>\n {totalCount} result{totalCount !== 1 ? 's' : ''} for “{debouncedSearchQuery}\n ”\n </span>\n )}\n </div>\n )}\n </div>\n\n {/* Filter Bar */}\n <div className=\"mt-4 flex flex-wrap items-center gap-3\">\n {/* Filter Toggle Button */}\n <button\n type=\"button\"\n data-tour=\"store-marketplace-filters-button\"\n onClick={() => setShowFilters(!showFilters)}\n className={`cursor-pointer flex items-center gap-2 rounded-lg border px-3 py-2 text-sm font-medium transition-colors ${\n showFilters || activeFilterCount > 0\n ? 'border-action-primary-border bg-action-primary-bg/10 text-text-link'\n : 'border-border-default bg-bg-surface text-text-primary transition-colors hover:bg-bg-sunken'\n }`}\n >\n <SlidersHorizontal className=\"size-4\" />\n {t('pages.marketplace.filters', { defaultValue: 'Filters' })}\n {activeFilterCount > 0 && (\n <span className=\"flex size-5 items-center justify-center rounded-full bg-action-primary-bg text-xs text-action-primary-text\">\n {activeFilterCount}\n </span>\n )}\n </button>\n\n {/* Quick Filter Chips - Always visible */}\n <div\n className=\"flex flex-wrap items-center gap-2\"\n data-tour=\"store-marketplace-quick-filters\"\n >\n <button\n type=\"button\"\n onClick={() => setPricingFilter(pricingFilter === 'free' ? 'all' : 'free')}\n className={`cursor-pointer flex items-center gap-1.5 rounded-full px-3 py-1.5 text-sm font-medium transition-colors ${\n pricingFilter === 'free'\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-sunken text-text-primary transition-colors hover:bg-bg-surface'\n }`}\n >\n <Gift className=\"size-3.5\" />\n Free\n </button>\n <button\n type=\"button\"\n onClick={() => setRatingFilter(ratingFilter === '4' ? 'any' : '4')}\n className={`cursor-pointer flex items-center gap-1.5 rounded-full px-3 py-1.5 text-sm font-medium transition-colors ${\n ratingFilter === '4'\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-sunken text-text-primary transition-colors hover:bg-bg-surface'\n }`}\n >\n <Star className=\"size-3.5\" />\n 4+ Stars\n </button>\n <button\n type=\"button\"\n onClick={() => setFeaturedOnly(!featuredOnly)}\n className={`cursor-pointer flex items-center gap-1.5 rounded-full px-3 py-1.5 text-sm font-medium transition-colors ${\n featuredOnly\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-sunken text-text-primary transition-colors hover:bg-bg-surface'\n }`}\n >\n <Sparkles className=\"size-3.5\" />\n Featured\n </button>\n </div>\n\n {/* Clear Filters */}\n {hasActiveFilters && (\n <button\n type=\"button\"\n onClick={clearAllFilters}\n className=\"cursor-pointer flex items-center gap-1 text-sm text-text-muted transition-colors hover:text-text-primary\"\n >\n <X className=\"size-4\" aria-hidden=\"true\" />\n Clear all\n </button>\n )}\n\n {/* Sort Dropdown - Right aligned */}\n <div className=\"ml-auto\" data-tour=\"store-marketplace-section-sort\">\n <FilterDropdown\n label=\"Sort\"\n value={sortOption}\n options={sortOptions}\n onChange={(value) => setSortOption(value as SortOption)}\n />\n </div>\n </div>\n\n {/* Expanded Filters Panel */}\n {showFilters && (\n <div className=\"mt-4 rounded-lg border border-border-default bg-bg-surface p-4\">\n <div className=\"flex flex-wrap items-start gap-6\">\n {/* Pricing Filter */}\n <div className=\"flex flex-col gap-2\">\n <span className=\"text-xs font-medium uppercase tracking-wider text-text-muted\">\n Pricing\n </span>\n <FilterDropdown\n label=\"Price\"\n value={pricingFilter}\n options={pricingOptions}\n onChange={(value) => setPricingFilter(value as PricingFilter)}\n />\n </div>\n\n {/* Rating Filter */}\n <div className=\"flex flex-col gap-2\">\n <span className=\"text-xs font-medium uppercase tracking-wider text-text-muted\">\n Min Rating\n </span>\n <FilterDropdown\n label=\"Rating\"\n value={ratingFilter}\n options={ratingOptions}\n onChange={(value) => setRatingFilter(value as RatingFilter)}\n />\n </div>\n\n {/* Category Filter */}\n {categoryOptions.length > 1 && (\n <div className=\"flex flex-col gap-2\">\n <span className=\"text-xs font-medium uppercase tracking-wider text-text-muted\">\n Category\n </span>\n <FilterDropdown\n label=\"Category\"\n value={selectedCategory}\n options={categoryOptions}\n onChange={setSelectedCategory}\n />\n </div>\n )}\n\n {/* Nature Filter (Digital/Physical) */}\n <div className=\"flex flex-col gap-2\">\n <span className=\"text-xs font-medium uppercase tracking-wider text-text-muted\">\n Nature\n </span>\n <FilterDropdown\n label=\"Nature\"\n value={natureFilter}\n options={natureOptions}\n onChange={(value) => setNatureFilter(value as NatureFilter)}\n />\n </div>\n\n {/* License Filter */}\n {licenseOptions.length > 1 && (\n <div className=\"flex flex-col gap-2\">\n <span className=\"text-xs font-medium uppercase tracking-wider text-text-muted\">\n License\n </span>\n <FilterDropdown\n label=\"License\"\n value={selectedLicense}\n options={licenseOptions}\n onChange={setSelectedLicense}\n />\n </div>\n )}\n </div>\n\n {/* Active Filters Summary */}\n {activeFilterCount > 0 && (\n <div className=\"mt-4 flex flex-wrap items-center gap-2 border-t border-border-default pt-4\">\n <span className=\"text-xs font-medium text-text-muted\">Active filters:</span>\n {selectedType !== 'all' && (\n <button\n type=\"button\"\n onClick={() => setSelectedType('all')}\n className=\"inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-action-primary-border bg-action-primary-bg/5 px-3 py-1.5 text-xs font-medium text-text-link shadow-sm transition-colors hover:bg-action-primary-bg/15\"\n >\n <span className=\"text-text-muted\">Type:</span> {selectedType}\n <X className=\"size-3\" aria-hidden=\"true\" />\n </button>\n )}\n {pricingFilter !== 'all' && (\n <button\n type=\"button\"\n onClick={() => setPricingFilter('all')}\n className=\"inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-action-primary-border bg-action-primary-bg/5 px-3 py-1.5 text-xs font-medium text-text-link shadow-sm transition-colors hover:bg-action-primary-bg/15\"\n >\n <span className=\"text-text-muted\">Price:</span>{' '}\n {pricingOptions.find((o) => o.value === pricingFilter)?.label}\n <X className=\"size-3\" aria-hidden=\"true\" />\n </button>\n )}\n {ratingFilter !== 'any' && (\n <button\n type=\"button\"\n onClick={() => setRatingFilter('any')}\n className=\"inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-action-primary-border bg-action-primary-bg/5 px-3 py-1.5 text-xs font-medium text-text-link shadow-sm transition-colors hover:bg-action-primary-bg/15\"\n >\n <span className=\"text-text-muted\">Rating:</span>{' '}\n {ratingOptions.find((o) => o.value === ratingFilter)?.label}\n <X className=\"size-3\" aria-hidden=\"true\" />\n </button>\n )}\n {selectedCategory !== 'all' && (\n <button\n type=\"button\"\n onClick={() => setSelectedCategory('all')}\n className=\"inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-action-primary-border bg-action-primary-bg/5 px-3 py-1.5 text-xs font-medium text-text-link shadow-sm transition-colors hover:bg-action-primary-bg/15\"\n >\n <span className=\"text-text-muted\">Category:</span> {selectedCategory}\n <X className=\"size-3\" aria-hidden=\"true\" />\n </button>\n )}\n {natureFilter !== 'all' && (\n <button\n type=\"button\"\n onClick={() => setNatureFilter('all')}\n className=\"inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-action-primary-border bg-action-primary-bg/5 px-3 py-1.5 text-xs font-medium text-text-link shadow-sm transition-colors hover:bg-action-primary-bg/15\"\n >\n <span className=\"text-text-muted\">Nature:</span>{' '}\n {natureOptions.find((o) => o.value === natureFilter)?.label}\n <X className=\"size-3\" aria-hidden=\"true\" />\n </button>\n )}\n {selectedLicense !== 'all' && (\n <button\n type=\"button\"\n onClick={() => setSelectedLicense('all')}\n className=\"inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-action-primary-border bg-action-primary-bg/5 px-3 py-1.5 text-xs font-medium text-text-link shadow-sm transition-colors hover:bg-action-primary-bg/15\"\n >\n <span className=\"text-text-muted\">License:</span>{' '}\n {licenseOptions.find((o) => o.value === selectedLicense)?.label}\n <X className=\"size-3\" aria-hidden=\"true\" />\n </button>\n )}\n {featuredOnly && (\n <button\n type=\"button\"\n onClick={() => setFeaturedOnly(false)}\n className=\"inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-action-primary-border bg-action-primary-bg/5 px-3 py-1.5 text-xs font-medium text-text-link shadow-sm transition-colors hover:bg-action-primary-bg/15\"\n >\n <Sparkles className=\"size-3\" />\n Featured Only\n <X className=\"size-3\" aria-hidden=\"true\" />\n </button>\n )}\n </div>\n )}\n </div>\n )}\n </header>\n\n {/* Main Content */}\n <main className=\"flex-1 overflow-y-auto\">\n <div className=\"mx-auto max-w-7xl space-y-8 p-6\">\n {/* Error State */}\n {error && (\n <div\n role=\"alert\"\n className=\"flex flex-col items-center justify-center rounded-xl border border-status-error-border bg-status-error-bg-subtle p-8 text-center\"\n >\n <AlertCircle className=\"mb-4 size-12 text-status-error-text\" />\n <h3 className=\"mb-2 text-lg font-semibold text-status-error-text-emphasis\">\n Failed to load marketplace\n </h3>\n <p className=\"mb-4 text-sm text-status-error-text\">\n {error.message || 'An error occurred while fetching products'}\n </p>\n <button\n type=\"button\"\n onClick={() => refetch()}\n className=\"cursor-pointer rounded-lg bg-status-error-bg px-4 py-2 text-sm font-medium text-status-error-text transition-colors hover:bg-status-error-bg-emphasis\"\n >\n Try Again\n </button>\n </div>\n )}\n\n {/* Loading State */}\n {loading && !error && <MarketplacePageSkeleton />}\n\n {/* Content - Only show when data is loaded */}\n {!loading && !error && (\n <>\n {/* Hero Section - Featured Products (only when no filters) */}\n {!hasActiveFilters && selectedType === 'all' && featured.length > 0 && (\n <HeroSection\n dataTour=\"store-marketplace-hero-section\"\n featuredProducts={featured}\n onProductClick={handleProductClick}\n />\n )}\n\n {/* Type Filter Categories */}\n {typeCategories.length > 1 && (\n <div>\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">Browse by Type</h2>\n <div\n className=\"flex flex-wrap gap-2\"\n data-tour=\"store-marketplace-type-categories\"\n >\n {typeCategories.map((category) => (\n <CategoryChip\n key={category.id}\n typeId={category.id}\n name={category.name}\n count={category.count}\n active={selectedType === category.id}\n onClick={() => setSelectedType(category.id)}\n />\n ))}\n </div>\n </div>\n )}\n\n {/* Show Filtered Results when filters are active */}\n {hasActiveFilters && (\n <section>\n <SectionHeader\n icon={Filter}\n title={debouncedSearchQuery ? `Search Results` : 'Filtered Results'}\n subtitle={`${totalCount} app${totalCount !== 1 ? 's' : ''} found`}\n />\n {filteredProducts.length > 0 ? (\n <div\n className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\"\n data-tour=\"store-marketplace-product-grid\"\n >\n {filteredProducts.map((product) => (\n <AppCard\n key={product.id}\n product={product}\n onClick={() => handleProductClick(product)}\n />\n ))}\n </div>\n ) : (\n <div className=\"flex flex-col items-center justify-center rounded-xl border border-border-default bg-bg-surface p-8 text-center\">\n <Filter className=\"mb-4 size-12 text-text-muted\" />\n <h3 className=\"mb-2 text-lg font-semibold text-text-primary\">\n No apps match your filters\n </h3>\n <p className=\"mb-4 text-sm text-text-muted\">\n Try adjusting your filter criteria or clearing filters to see more results.\n </p>\n <button\n type=\"button\"\n onClick={clearAllFilters}\n className=\"cursor-pointer rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-opacity hover:opacity-90\"\n >\n Clear All Filters\n </button>\n </div>\n )}\n </section>\n )}\n\n {/* Show grouped sections only when no filters are active */}\n {!hasActiveFilters && selectedType === 'all' && (\n <>\n {/* Most Downloaded / Trending Apps */}\n {mostDownloaded.length > 0 && (\n <section>\n <SectionHeader\n icon={TrendingUp}\n title=\"Most Downloaded\"\n subtitle=\"Top picks by our community\"\n />\n <div\n className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\"\n data-tour=\"store-marketplace-most-downloaded\"\n >\n {mostDownloaded.slice(0, 6).map((product) => (\n <AppCard\n key={product.id}\n product={product}\n onClick={() => handleProductClick(product)}\n />\n ))}\n </div>\n </section>\n )}\n\n {/* Recently Added / New Releases */}\n {recentlyAdded.length > 0 && (\n <section>\n <SectionHeader\n icon={Clock}\n title=\"New Releases\"\n subtitle=\"Recently published apps\"\n />\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {recentlyAdded.slice(0, 6).map((product) => (\n <AppCard\n key={product.id}\n product={product}\n onClick={() => handleProductClick(product)}\n />\n ))}\n </div>\n </section>\n )}\n\n {/* Free Items */}\n {freeItems.length > 0 && (\n <section>\n <SectionHeader\n icon={Gift}\n title=\"Free Apps\"\n subtitle=\"No cost, full functionality\"\n />\n <div className=\"grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-6\">\n {freeItems.slice(0, 6).map((product) => (\n <AppCard\n key={product.id}\n product={product}\n onClick={() => handleProductClick(product)}\n variant=\"compact\"\n />\n ))}\n </div>\n </section>\n )}\n\n {/* All Apps */}\n {allProducts.length > 0 && (\n <section>\n <SectionHeader\n icon={Box}\n title=\"All Apps\"\n subtitle={`${allProducts.length} apps available`}\n />\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n {allProducts.map((product) => (\n <AppCard\n key={product.id}\n product={product}\n onClick={() => handleProductClick(product)}\n />\n ))}\n </div>\n </section>\n )}\n </>\n )}\n\n {/* Empty State - No products at all */}\n {allProducts.length === 0 && (\n <div className=\"flex flex-col items-center justify-center rounded-xl border border-border-default bg-bg-surface p-12 text-center\">\n <Box className=\"mb-4 size-16 text-text-muted\" />\n <h3 className=\"mb-2 text-xl font-semibold text-text-primary\">\n No apps available yet\n </h3>\n <p className=\"max-w-md text-text-muted\">\n The marketplace is empty. Check back soon for new apps, workflows, and\n integrations.\n </p>\n </div>\n )}\n </>\n )}\n </div>\n </main>\n\n {/* Cart Drawer */}\n <CartDrawer\n isOpen={cartOpen}\n onClose={closeCart}\n onCheckout={handleCheckout}\n cartItems={cartItems}\n itemCount={itemCount}\n subtotal={subtotal}\n tax={tax}\n total={total}\n updateQuantity={updateQuantity}\n removeProduct={removeProduct}\n />\n </div>\n );\n};\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { getMainDefinition as e } from "../node_modules/@apollo/client/utilities/internal/getMainDefinition.js";
|
|
2
|
-
import { GraphQLWsLink as t } from "../node_modules/@apollo/client/link/subscriptions/index.js";
|
|
3
|
-
import { createClient as n } from "../node_modules/graphql-ws/dist/client.js";
|
|
1
|
+
import { getMainDefinition as e } from "../node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getMainDefinition.js";
|
|
2
|
+
import { GraphQLWsLink as t } from "../node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/link/subscriptions/index.js";
|
|
3
|
+
import { createClient as n } from "../node_modules/.bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws/dist/client.js";
|
|
4
4
|
import { createContext as r, use as i, useMemo as a } from "react";
|
|
5
5
|
import { ApolloClient as o, InMemoryCache as s, createHttpLink as c, from as l, split as u } from "@apollo/client/core";
|
|
6
6
|
import { ApolloProvider as d } from "@apollo/client/react";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/microfe-store",
|
|
3
|
-
"version": "2026.624.
|
|
3
|
+
"version": "2026.624.6",
|
|
4
4
|
"description": "Store microfrontend for Burdenoff products",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@apollo/client": "^4.0.11",
|
|
43
|
-
"@burdenoff/fe-libs": "
|
|
43
|
+
"@burdenoff/fe-libs": "workspace:*",
|
|
44
44
|
"@tanstack/react-query": "^5.90.16",
|
|
45
45
|
"clsx": "^2.1.1",
|
|
46
46
|
"graphql": "^16.10.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CombinedGraphQLErrors.js","names":[],"sources":["../../../../../node_modules/@apollo/client/errors/CombinedGraphQLErrors.js"],"sourcesContent":["import { brand, isBranded } from \"./utils.js\";\nfunction defaultFormatMessage(errors) {\n return (errors\n // Handle non-spec-compliant servers: See #1185\n .filter((e) => e)\n .map((e) => e.message || \"Error message not found.\")\n .join(\"\\n\"));\n}\n/**\n * Represents the combined list of GraphQL errors returned from the server in a\n * GraphQL response. This error type is used when your GraphQL operation returns\n * errors in the `errors` field of the response.\n *\n * @remarks\n *\n * When your GraphQL operation encounters errors on the server side (such as\n * resolver errors, validation errors, or syntax errors), the server returns\n * these errors in the `errors` array of the GraphQL response. Apollo Client\n * wraps these errors in a `CombinedGraphQLErrors` object, which provides access\n * to the individual errors while maintaining additional context about the\n * response.\n *\n * @example\n *\n * ```ts\n * import { CombinedGraphQLErrors } from \"@apollo/client/errors\";\n *\n * // Check if an error is a CombinedGraphQLErrors object\n * if (CombinedGraphQLErrors.is(error)) {\n * // Access individual GraphQL errors\n * error.errors.forEach((graphQLError) => {\n * console.log(graphQLError.message);\n * console.log(graphQLError.path);\n * console.log(graphQLError.locations);\n * });\n *\n * // Access the original GraphQL result\n * console.log(error.result);\n * }\n * ```\n */\nexport class CombinedGraphQLErrors extends Error {\n /**\n * A method that determines whether an error is a `CombinedGraphQLErrors`\n * object. This method enables TypeScript to narrow the error type.\n * \n * @example\n * \n * ```ts\n * if (CombinedGraphQLErrors.is(error)) {\n * // TypeScript now knows `error` is a `CombinedGraphQLErrors` object\n * console.log(error.errors);\n * }\n * ```\n */\n static is(error) {\n return isBranded(error, \"CombinedGraphQLErrors\");\n }\n /**\n * A function that formats the error message used for the error's `message`\n * property. Override this method to provide your own formatting.\n * \n * @remarks\n * \n * The `formatMessage` function is called by the `CombinedGraphQLErrors`\n * constructor to provide a formatted message as the `message` property of the\n * `CombinedGraphQLErrors` object. Follow the [\"Providing a custom message\n * formatter\"](https://www.apollographql.com/docs/react/api/errors/CombinedGraphQLErrors#providing-a-custom-message-formatter) guide to learn how to modify the message format.\n * \n * @param errors - The array of GraphQL errors returned from the server in\n * the `errors` field of the response.\n * @param options - Additional context that could be useful when formatting\n * the message.\n */\n static formatMessage = defaultFormatMessage;\n /**\n * The raw list of GraphQL errors returned by the `errors` field in the GraphQL response.\n */\n errors;\n /**\n * Partial data returned in the `data` field of the GraphQL response.\n */\n data;\n /**\n * Extensions returned by the `extensions` field in the GraphQL response.\n */\n extensions;\n constructor(result, errors = result.errors || []) {\n super(CombinedGraphQLErrors.formatMessage(errors, {\n result,\n defaultFormatMessage,\n }));\n this.errors = errors;\n this.data = result.data;\n this.extensions = result.extensions;\n this.name = \"CombinedGraphQLErrors\";\n brand(this);\n Object.setPrototypeOf(this, CombinedGraphQLErrors.prototype);\n }\n}\n//# sourceMappingURL=CombinedGraphQLErrors.js.map\n"],"x_google_ignoreList":[0],"mappings":";;AACA,SAAS,EAAqB,GAAQ;AAClC,QAAQ,EAEH,QAAQ,MAAM,EAAE,CAChB,KAAK,MAAM,EAAE,WAAW,2BAA2B,CACnD,KAAK,KAAK;;AAmCnB,IAAa,IAAb,MAAa,UAA8B,MAAM;CAc7C,OAAO,GAAG,GAAO;AACb,SAAO,EAAU,GAAO,wBAAwB;;CAkBpD,OAAO,gBAAgB;CAIvB;CAIA;CAIA;CACA,YAAY,GAAQ,IAAS,EAAO,UAAU,EAAE,EAAE;AAU9C,EATA,MAAM,EAAsB,cAAc,GAAQ;GAC9C;GACA;GACH,CAAC,CAAC,EACH,KAAK,SAAS,GACd,KAAK,OAAO,EAAO,MACnB,KAAK,aAAa,EAAO,YACzB,KAAK,OAAO,yBACZ,EAAM,KAAK,EACX,OAAO,eAAe,MAAM,EAAsB,UAAU"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","names":[],"sources":["../../../../../node_modules/@apollo/client/errors/utils.js"],"sourcesContent":["export function isBranded(error, name) {\n return (typeof error === \"object\" &&\n error !== null &&\n error[Symbol.for(\"apollo.error\")] === name);\n}\nexport function brand(error) {\n Object.defineProperty(error, Symbol.for(\"apollo.error\"), {\n value: error.name,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n}\n//# sourceMappingURL=utils.js.map"],"x_google_ignoreList":[0],"mappings":";AAAA,SAAgB,EAAU,GAAO,GAAM;AACnC,QAAQ,OAAO,KAAU,cACrB,KACA,EAAM,OAAO,IAAI,eAAe,MAAM;;AAE9C,SAAgB,EAAM,GAAO;AACzB,QAAO,eAAe,GAAO,OAAO,IAAI,eAAe,EAAE;EACrD,OAAO,EAAM;EACb,YAAY;EACZ,UAAU;EACV,cAAc;EACjB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ApolloLink.js","names":[],"sources":["../../../../../../node_modules/@apollo/client/link/core/ApolloLink.js"],"sourcesContent":["import { EMPTY } from \"rxjs\";\nimport { createOperation } from \"@apollo/client/link/utils\";\nimport { __DEV__ } from \"@apollo/client/utilities/environment\";\nimport { invariant, newInvariantError, } from \"@apollo/client/utilities/invariant\";\n/**\n * The base class for all links in Apollo Client. A link represents either a\n * self-contained modification to a GraphQL operation or a side effect (such as\n * logging).\n *\n * @remarks\n *\n * Links enable you to customize Apollo Client's request flow by composing\n * together different pieces of functionality into a chain of links. Each\n * link represents a specific capability, such as adding authentication headers,\n * retrying failed requests, batching operations, or sending requests to a\n * GraphQL server.\n *\n * Every link must define a request handler via its constructor or by extending\n * this class and implementing the `request` method.\n *\n * @example\n *\n * ```ts\n * import { ApolloLink } from \"@apollo/client\";\n *\n * const link = new ApolloLink((operation, forward) => {\n * console.log(\"Operation:\", operation.operationName);\n * return forward(operation);\n * });\n * ```\n */\nexport class ApolloLink {\n /**\n * Creates a link that completes immediately and does not emit a result.\n *\n * @example\n *\n * ```ts\n * const link = ApolloLink.empty();\n * ```\n */\n static empty() {\n return new ApolloLink(() => EMPTY);\n }\n /**\n * Composes multiple links into a single composed link that executes each\n * provided link in serial order.\n *\n * @example\n *\n * ```ts\n * import { from, HttpLink, ApolloLink } from \"@apollo/client\";\n * import { RetryLink } from \"@apollo/client/link/retry\";\n * import MyAuthLink from \"../auth\";\n *\n * const link = ApolloLink.from([\n * new RetryLink(),\n * new MyAuthLink(),\n * new HttpLink({ uri: \"http://localhost:4000/graphql\" }),\n * ]);\n * ```\n *\n * @param links - An array of `ApolloLink` instances or request handlers that\n * are executed in serial order.\n */\n static from(links) {\n if (links.length === 0)\n return ApolloLink.empty();\n const [first, ...rest] = links;\n return first.concat(...rest);\n }\n /**\n * Creates a link that conditionally routes a request to different links.\n *\n * @example\n *\n * ```ts\n * import { ApolloLink, HttpLink } from \"@apollo/client\";\n *\n * const link = ApolloLink.split(\n * (operation) => operation.getContext().version === 1,\n * new HttpLink({ uri: \"http://localhost:4000/v1/graphql\" }),\n * new HttpLink({ uri: \"http://localhost:4000/v2/graphql\" })\n * );\n * ```\n *\n * @param test - A predicate function that receives the current `operation`\n * and returns a boolean indicating which link to execute. Returning `true`\n * executes the `left` link. Returning `false` executes the `right` link.\n *\n * @param left - The link that executes when the `test` function returns\n * `true`.\n *\n * @param right - The link that executes when the `test` function returns\n * `false`. If the `right` link is not provided, the request is forwarded to\n * the next link in the chain.\n */\n static split(test, left, right = new ApolloLink((op, forward) => forward(op))) {\n const link = new ApolloLink((operation, forward) => {\n const result = test(operation);\n if (__DEV__) {\n if (typeof result !== \"boolean\") {\n __DEV__ && invariant.warn(63, result);\n }\n }\n return result ?\n left.request(operation, forward)\n : right.request(operation, forward);\n });\n return Object.assign(link, { left, right });\n }\n /**\n * Executes a GraphQL request against a link. The `execute` function begins\n * the request by calling the request handler of the link.\n *\n * @example\n *\n * ```ts\n * const observable = ApolloLink.execute(link, { query, variables }, { client });\n *\n * observable.subscribe({\n * next(value) {\n * console.log(\"Received\", value);\n * },\n * error(error) {\n * console.error(\"Oops got error\", error);\n * },\n * complete() {\n * console.log(\"Request complete\");\n * },\n * });\n * ```\n *\n * @param link - The `ApolloLink` instance to execute the request.\n *\n * @param request - The GraphQL request details, such as the `query` and\n * `variables`.\n *\n * @param context - The execution context for the request, such as the\n * `client` making the request.\n */\n static execute(link, request, context) {\n return link.request(createOperation(request, context), () => {\n if (__DEV__) {\n __DEV__ && invariant.warn(64);\n }\n return EMPTY;\n });\n }\n /**\n * Combines multiple links into a single composed link.\n *\n * @example\n *\n * ```ts\n * const link = ApolloLink.concat(firstLink, secondLink, thirdLink);\n * ```\n *\n * @param links - The links to concatenate into a single link. Each link will\n * execute in serial order.\n *\n * @deprecated Use `ApolloLink.from` instead. `ApolloLink.concat` will be\n * removed in a future major version.\n */\n static concat(...links) {\n return ApolloLink.from(links);\n }\n constructor(request) {\n if (request)\n this.request = request;\n }\n /**\n * Concatenates a link that conditionally routes a request to different links.\n *\n * @example\n *\n * ```ts\n * import { ApolloLink, HttpLink } from \"@apollo/client\";\n *\n * const previousLink = new ApolloLink((operation, forward) => {\n * // Handle the request\n *\n * return forward(operation);\n * });\n *\n * const link = previousLink.split(\n * (operation) => operation.getContext().version === 1,\n * new HttpLink({ uri: \"http://localhost:4000/v1/graphql\" }),\n * new HttpLink({ uri: \"http://localhost:4000/v2/graphql\" })\n * );\n * ```\n *\n * @param test - A predicate function that receives the current `operation`\n * and returns a boolean indicating which link to execute. Returning `true`\n * executes the `left` link. Returning `false` executes the `right` link.\n *\n * @param left - The link that executes when the `test` function returns\n * `true`.\n *\n * @param right - The link that executes when the `test` function returns\n * `false`. If the `right` link is not provided, the request is forwarded to\n * the next link in the chain.\n */\n split(test, left, right) {\n return this.concat(ApolloLink.split(test, left, right));\n }\n /**\n * Combines the link with other links into a single composed link.\n *\n * @example\n *\n * ```ts\n * import { ApolloLink, HttpLink } from \"@apollo/client\";\n *\n * const previousLink = new ApolloLink((operation, forward) => {\n * // Handle the request\n *\n * return forward(operation);\n * });\n *\n * const link = previousLink.concat(\n * link1,\n * link2,\n * new HttpLink({ uri: \"http://localhost:4000/graphql\" })\n * );\n * ```\n */\n concat(...links) {\n if (links.length === 0) {\n return this;\n }\n return links.reduce(this.combine.bind(this), this);\n }\n combine(left, right) {\n const link = new ApolloLink((operation, forward) => {\n return left.request(operation, (op) => right.request(op, forward));\n });\n return Object.assign(link, { left, right });\n }\n /**\n * Runs the request handler for the provided operation.\n *\n * > [!NOTE]\n * > This is called by the `ApolloLink.execute` function for you and should\n * > not be called directly. Prefer using `ApolloLink.execute` to make the\n * > request instead.\n */\n request(operation, forward) {\n throw newInvariantError(65);\n }\n /**\n * @internal\n * Used to iterate through all links that are concatenations or `split` links.\n * \n * @deprecated This is an internal API and should not be used directly. This can be removed or changed at any time.\n */\n left;\n /**\n * @internal\n * Used to iterate through all links that are concatenations or `split` links.\n * \n * @deprecated This is an internal API and should not be used directly. This can be removed or changed at any time.\n */\n right;\n}\n//# sourceMappingURL=ApolloLink.js.map\n"],"x_google_ignoreList":[0],"mappings":";;;;AA+BA,IAAa,IAAb,MAAa,EAAW;CAUpB,OAAO,QAAQ;AACX,SAAO,IAAI,QAAiB,EAAM;;CAuBtC,OAAO,KAAK,GAAO;AACf,MAAI,EAAM,WAAW,EACjB,QAAO,EAAW,OAAO;EAC7B,IAAM,CAAC,GAAO,GAAG,KAAQ;AACzB,SAAO,EAAM,OAAO,GAAG,EAAK;;CA4BhC,OAAO,MAAM,GAAM,GAAM,IAAQ,IAAI,GAAY,GAAI,MAAY,EAAQ,EAAG,CAAC,EAAE;EAC3E,IAAM,IAAO,IAAI,GAAY,GAAW,MACrB,EAAK,EAAU,GAO1B,EAAK,QAAQ,GAAW,EAAQ,GAC9B,EAAM,QAAQ,GAAW,EAAQ,CACzC;AACF,SAAO,OAAO,OAAO,GAAM;GAAE;GAAM;GAAO,CAAC;;CAgC/C,OAAO,QAAQ,GAAM,GAAS,GAAS;AACnC,SAAO,EAAK,QAAQ,EAAgB,GAAS,EAAQ,QAI1C,EACT;;CAiBN,OAAO,OAAO,GAAG,GAAO;AACpB,SAAO,EAAW,KAAK,EAAM;;CAEjC,YAAY,GAAS;AACjB,EAAI,MACA,KAAK,UAAU;;CAkCvB,MAAM,GAAM,GAAM,GAAO;AACrB,SAAO,KAAK,OAAO,EAAW,MAAM,GAAM,GAAM,EAAM,CAAC;;CAuB3D,OAAO,GAAG,GAAO;AAIb,SAHI,EAAM,WAAW,IACV,OAEJ,EAAM,OAAO,KAAK,QAAQ,KAAK,KAAK,EAAE,KAAK;;CAEtD,QAAQ,GAAM,GAAO;EACjB,IAAM,IAAO,IAAI,GAAY,GAAW,MAC7B,EAAK,QAAQ,IAAY,MAAO,EAAM,QAAQ,GAAI,EAAQ,CAAC,CACpE;AACF,SAAO,OAAO,OAAO,GAAM;GAAE;GAAM;GAAO,CAAC;;CAU/C,QAAQ,GAAW,GAAS;AACxB,QAAM,EAAkB,GAAG;;CAQ/B;CAOA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../../../node_modules/@apollo/client/link/subscriptions/index.js"],"sourcesContent":["// This file is adapted from the graphql-ws npm package:\n// https://github.com/enisdenjo/graphql-ws\n//\n// Most of the file comes from that package's README; some other parts (such as\n// isLikeCloseEvent) come from its source.\n//\n// Here's the license of the original code:\n//\n// The MIT License (MIT)\n//\n// Copyright (c) 2020-2021 Denis Badurina\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\nimport { Observable } from \"rxjs\";\nimport { CombinedGraphQLErrors } from \"@apollo/client/errors\";\nimport { ApolloLink } from \"@apollo/client/link\";\nimport { print } from \"@apollo/client/utilities\";\nimport { isNonNullObject } from \"@apollo/client/utilities/internal\";\n// https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close_event\nfunction isLikeCloseEvent(val) {\n return isNonNullObject(val) && \"code\" in val && \"reason\" in val;\n}\n// https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/error_event\nfunction isLikeErrorEvent(err) {\n return isNonNullObject(err) && err.target?.readyState === WebSocket.CLOSED;\n}\n/**\n * The `GraphQLWsLink` is a terminating link sends GraphQL operations over a\n * WebSocket connection using the [`graphql-ws`](https://www.npmjs.com/package/graphql-ws) library. It's used most\n * commonly with GraphQL [subscriptions](https://apollographql.com/docs/react/data/subscriptions/),\n *\n * > [!NOTE]\n * > This link works with the `graphql-ws` library. If your server uses\n * > the deprecated `subscriptions-transport-ws` library, use the deprecated\n * > [`WebSocketLink`](https://apollographql.com/docs/react/api/link/apollo-link-ws) link instead.\n *\n * @example\n *\n * ```ts\n * import { GraphQLWsLink } from \"@apollo/client/link/subscriptions\";\n * import { createClient } from \"graphql-ws\";\n *\n * const link = new GraphQLWsLink(\n * createClient({\n * url: \"ws://localhost:3000/subscriptions\",\n * })\n * );\n * ```\n */\nexport class GraphQLWsLink extends ApolloLink {\n client;\n constructor(client) {\n super();\n this.client = client;\n }\n request(operation) {\n return new Observable((observer) => {\n const { query, variables, operationName, extensions } = operation;\n return this.client.subscribe({ variables, operationName, extensions, query: print(query) }, {\n next: observer.next.bind(observer),\n complete: observer.complete.bind(observer),\n error: (err) => {\n if (err instanceof Error) {\n return observer.error(err);\n }\n const likeClose = isLikeCloseEvent(err);\n if (likeClose || isLikeErrorEvent(err)) {\n return observer.error(\n // reason will be available on clean closes\n new Error(`Socket closed${likeClose ? ` with event ${err.code}` : \"\"}${likeClose ? ` ${err.reason}` : \"\"}`));\n }\n return observer.error(new CombinedGraphQLErrors({\n errors: Array.isArray(err) ? err : [err],\n }));\n },\n // casting around a wrong type in graphql-ws, which incorrectly expects `Sink<ExecutionResult>`\n });\n });\n }\n}\n//# sourceMappingURL=index.js.map"],"x_google_ignoreList":[0],"mappings":";;;;;;AAmCA,SAAS,EAAiB,GAAK;AAC3B,QAAO,EAAgB,EAAI,IAAI,UAAU,KAAO,YAAY;;AAGhE,SAAS,EAAiB,GAAK;AAC3B,QAAO,EAAgB,EAAI,IAAI,EAAI,QAAQ,eAAe,UAAU;;AAyBxE,IAAa,IAAb,cAAmC,EAAW;CAC1C;CACA,YAAY,GAAQ;AAEhB,EADA,OAAO,EACP,KAAK,SAAS;;CAElB,QAAQ,GAAW;AACf,SAAO,IAAI,GAAY,MAAa;GAChC,IAAM,EAAE,UAAO,cAAW,kBAAe,kBAAe;AACxD,UAAO,KAAK,OAAO,UAAU;IAAE;IAAW;IAAe;IAAY,OAAO,EAAM,EAAM;IAAE,EAAE;IACxF,MAAM,EAAS,KAAK,KAAK,EAAS;IAClC,UAAU,EAAS,SAAS,KAAK,EAAS;IAC1C,QAAQ,MAAQ;AACZ,SAAI,aAAe,MACf,QAAO,EAAS,MAAM,EAAI;KAE9B,IAAM,IAAY,EAAiB,EAAI;AAMvC,YALI,KAAa,EAAiB,EAAI,GAC3B,EAAS,MAEhB,gBAAI,MAAM,gBAAgB,IAAY,eAAe,EAAI,SAAS,KAAK,IAAY,IAAI,EAAI,WAAW,KAAK,CAAC,GAEzG,EAAS,MAAM,IAAI,EAAsB,EAC5C,QAAQ,MAAM,QAAQ,EAAI,GAAG,IAAM,CAAC,EAAI,EAC3C,CAAC,CAAC;;IAGV,CAAC;IACJ"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createOperation.js","names":[],"sources":["../../../../../../node_modules/@apollo/client/link/utils/createOperation.js"],"sourcesContent":["import { getOperationDefinition, getOperationName, } from \"@apollo/client/utilities/internal\";\nexport function createOperation(request, { client }) {\n const operation = {\n query: request.query,\n variables: request.variables || {},\n extensions: request.extensions || {},\n operationName: getOperationName(request.query),\n operationType: getOperationDefinition(request.query).operation,\n };\n let context = { ...request.context };\n const setContext = (next) => {\n if (typeof next === \"function\") {\n context = { ...context, ...next(getContext()) };\n }\n else {\n context = { ...context, ...next };\n }\n };\n const getContext = () => Object.freeze({ ...context });\n Object.defineProperty(operation, \"setContext\", {\n enumerable: false,\n value: setContext,\n });\n Object.defineProperty(operation, \"getContext\", {\n enumerable: false,\n value: getContext,\n });\n Object.defineProperty(operation, \"client\", {\n enumerable: false,\n value: client,\n });\n return operation;\n}\n//# sourceMappingURL=createOperation.js.map"],"x_google_ignoreList":[0],"mappings":";;;AACA,SAAgB,EAAgB,GAAS,EAAE,aAAU;CACjD,IAAM,IAAY;EACd,OAAO,EAAQ;EACf,WAAW,EAAQ,aAAa,EAAE;EAClC,YAAY,EAAQ,cAAc,EAAE;EACpC,eAAe,EAAiB,EAAQ,MAAM;EAC9C,eAAe,EAAuB,EAAQ,MAAM,CAAC;EACxD,EACG,IAAU,EAAE,GAAG,EAAQ,SAAS,EAC9B,KAAc,MAAS;AACzB,EAII,IAJA,OAAO,KAAS,aACN;GAAE,GAAG;GAAS,GAAG,EAAK,GAAY,CAAC;GAAE,GAGrC;GAAE,GAAG;GAAS,GAAG;GAAM;IAGnC,UAAmB,OAAO,OAAO,EAAE,GAAG,GAAS,CAAC;AAatD,QAZA,OAAO,eAAe,GAAW,cAAc;EAC3C,YAAY;EACZ,OAAO;EACV,CAAC,EACF,OAAO,eAAe,GAAW,cAAc;EAC3C,YAAY;EACZ,OAAO;EACV,CAAC,EACF,OAAO,eAAe,GAAW,UAAU;EACvC,YAAY;EACZ,OAAO;EACV,CAAC,EACK"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sizes.js","names":["global"],"sources":["../../../../../../node_modules/@apollo/client/utilities/caching/sizes.js"],"sourcesContent":["import { global } from \"@apollo/client/utilities/internal/globals\";\nconst cacheSizeSymbol = Symbol.for(\"apollo.cacheSize\");\n/**\n * The global cache size configuration for Apollo Client.\n *\n * @remarks\n *\n * You can directly modify this object, but any modification will\n * only have an effect on caches that are created after the modification.\n *\n * So for global caches, such as `canonicalStringify` and `print`,\n * you might need to call `.reset` on them, which will essentially re-create them.\n *\n * Alternatively, you can set `globalThis[Symbol.for(\"apollo.cacheSize\")]` before\n * you load the Apollo Client package:\n *\n * @example\n *\n * ```ts\n * globalThis[Symbol.for(\"apollo.cacheSize\")] = {\n * print: 100,\n * } satisfies Partial<CacheSizes>; // the `satisfies` is optional if using TypeScript\n * ```\n */\nexport const cacheSizes = { ...global[cacheSizeSymbol] };\n//# sourceMappingURL=sizes.js.map"],"x_google_ignoreList":[0],"mappings":";AAwBA,IAAa,IAAa,EAAE,GAAGA,EAvBP,OAAO,IAAI,mBAAmB,GAuBE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"print.js","names":["print","origPrint"],"sources":["../../../../../../node_modules/@apollo/client/utilities/graphql/print.js"],"sourcesContent":["import { print as origPrint } from \"graphql\";\nimport { __DEV__ } from \"@apollo/client/utilities/environment\";\nimport { AutoCleanedWeakCache, registerGlobalCache, } from \"@apollo/client/utilities/internal\";\nimport { cacheSizes } from \"../caching/index.js\";\nlet printCache;\n/**\n * Converts an AST into a string, using one set of reasonable\n * formatting rules.\n *\n * @remarks This is the same function as the GraphQL.js `print` function but\n * with an added cache to avoid recomputation when encountering the same\n * `ASTNode` more than once.\n */\nexport const print = Object.assign((ast) => {\n let result = printCache.get(ast);\n if (!result) {\n result = origPrint(ast);\n printCache.set(ast, result);\n }\n return result;\n}, {\n reset() {\n printCache = new AutoCleanedWeakCache(cacheSizes.print || 2000 /* defaultCacheSizes.print */);\n },\n});\nprint.reset();\nif (__DEV__) {\n registerGlobalCache(\"print\", () => (printCache ? printCache.size : 0));\n}\n//# sourceMappingURL=print.js.map"],"x_google_ignoreList":[0],"mappings":";;;;;AAIA,IAAI,GASSA,IAAQ,OAAO,QAAQ,MAAQ;CACxC,IAAI,IAAS,EAAW,IAAI,EAAI;AAKhC,QAJK,MACD,IAASC,EAAU,EAAI,EACvB,EAAW,IAAI,GAAK,EAAO,GAExB;GACR,EACC,QAAQ;AACJ,KAAa,IAAI,EAAqB,EAAW,SAAS,IAAmC;GAEpG,CAAC;AACFD,EAAM,OAAO"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"caches.js","names":[],"sources":["../../../../../../node_modules/@apollo/client/utilities/internal/caches.js"],"sourcesContent":["import { StrongCache, WeakCache } from \"@wry/caches\";\nconst scheduledCleanup = new WeakSet();\nfunction schedule(cache) {\n if (cache.size <= (cache.max || -1)) {\n return;\n }\n if (!scheduledCleanup.has(cache)) {\n scheduledCleanup.add(cache);\n setTimeout(() => {\n cache.clean();\n scheduledCleanup.delete(cache);\n }, 100);\n }\n}\n/**\n* @internal\n* A version of WeakCache that will auto-schedule a cleanup of the cache when\n* a new item is added and the cache reached maximum size.\n* Throttled to once per 100ms.\n*\n* @privateRemarks\n* Should be used throughout the rest of the codebase instead of WeakCache,\n* with the notable exception of usage in `wrap` from `optimism` - that one\n* already handles cleanup and should remain a `WeakCache`.\n* \n* @deprecated This is an internal API and should not be used directly. This can be removed or changed at any time.\n*/\nexport const AutoCleanedWeakCache = function (max, dispose) {\n /*\n Some builds of `WeakCache` are function prototypes, some are classes.\n This library still builds with an ES5 target, so we can't extend the\n real classes.\n Instead, we have to use this workaround until we switch to a newer build\n target.\n */\n const cache = new WeakCache(max, dispose);\n cache.set = function (key, value) {\n const ret = WeakCache.prototype.set.call(this, key, value);\n schedule(this);\n return ret;\n };\n return cache;\n};\n/**\n* @internal\n* A version of StrongCache that will auto-schedule a cleanup of the cache when\n* a new item is added and the cache reached maximum size.\n* Throttled to once per 100ms.\n*\n* @privateRemarks\n* Should be used throughout the rest of the codebase instead of StrongCache,\n* with the notable exception of usage in `wrap` from `optimism` - that one\n* already handles cleanup and should remain a `StrongCache`.\n* \n* @deprecated This is an internal API and should not be used directly. This can be removed or changed at any time.\n*/\nexport const AutoCleanedStrongCache = function (max, dispose) {\n /*\n Some builds of `StrongCache` are function prototypes, some are classes.\n This library still builds with an ES5 target, so we can't extend the\n real classes.\n Instead, we have to use this workaround until we switch to a newer build\n target.\n */\n const cache = new StrongCache(max, dispose);\n cache.set = function (key, value) {\n const ret = StrongCache.prototype.set.call(this, key, value);\n schedule(this);\n return ret;\n };\n return cache;\n};\n//# sourceMappingURL=caches.js.map\n"],"x_google_ignoreList":[0],"mappings":";;AACA,IAAM,oBAAmB,IAAI,SAAS;AACtC,SAAS,EAAS,GAAO;AACjB,GAAM,SAAS,EAAM,OAAO,OAG3B,EAAiB,IAAI,EAAM,KAC5B,EAAiB,IAAI,EAAM,EAC3B,iBAAiB;AAEb,EADA,EAAM,OAAO,EACb,EAAiB,OAAO,EAAM;IAC/B,IAAI;;AAgBf,IAAa,IAAuB,SAAU,GAAK,GAAS;CAQxD,IAAM,IAAQ,IAAI,EAAU,GAAK,EAAQ;AAMzC,QALA,EAAM,MAAM,SAAU,GAAK,GAAO;EAC9B,IAAM,IAAM,EAAU,UAAU,IAAI,KAAK,MAAM,GAAK,EAAM;AAE1D,SADA,EAAS,KAAK,EACP;IAEJ"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"checkDocument.js","names":[],"sources":["../../../../../../node_modules/@apollo/client/utilities/internal/checkDocument.js"],"sourcesContent":["// Checks the document for errors and throws an exception if there is an error.\nimport { Kind, visit } from \"graphql\";\nimport { __DEV__ } from \"@apollo/client/utilities/environment\";\nimport { invariant, newInvariantError, } from \"@apollo/client/utilities/invariant\";\nimport { cacheSizes } from \"../caching/sizes.js\";\nimport { getOperationName } from \"./getOperationName.js\";\nimport { memoize } from \"./memoize.js\";\n/**\n* Checks the document for errors and throws an exception if there is an error.\n*\n* @internal\n* \n* @deprecated This is an internal API and should not be used directly. This can be removed or changed at any time.\n*/\nexport const checkDocument = memoize((doc, expectedType) => {\n invariant(doc && doc.kind === \"Document\", 1);\n const operations = doc.definitions.filter((d) => d.kind === \"OperationDefinition\");\n if (__DEV__) {\n doc.definitions.forEach((definition) => {\n if (definition.kind !== \"OperationDefinition\" &&\n definition.kind !== \"FragmentDefinition\") {\n throw newInvariantError(2, definition.kind);\n }\n });\n invariant(operations.length <= 1, 3, operations.length);\n }\n if (expectedType) {\n invariant(\n operations.length == 1 && operations[0].operation === expectedType,\n 4,\n expectedType,\n expectedType,\n operations[0].operation\n );\n }\n visit(doc, {\n Field(field, _, __, path) {\n if (field.alias &&\n (field.alias.value === \"__typename\" ||\n field.alias.value.startsWith(\"__ac_\")) &&\n field.alias.value !== field.name.value) {\n // not using `invariant` so path calculation only happens in error case\n let current = doc, fieldPath = [];\n for (const key of path) {\n current = current[key];\n if (current.kind === Kind.FIELD) {\n fieldPath.push(current.alias?.value || current.name.value);\n }\n }\n fieldPath.splice(-1, 1, field.name.value);\n throw newInvariantError(\n 5,\n field.alias.value,\n fieldPath.join(\".\"),\n operations[0].operation,\n getOperationName(doc, \"(anonymous)\")\n );\n }\n },\n });\n}, {\n max: cacheSizes[\"checkDocument\"] || 2000 /* defaultCacheSizes[\"checkDocument\"] */,\n});\n//# sourceMappingURL=checkDocument.js.map\n"],"x_google_ignoreList":[0],"mappings":";;;;;;AAcA,IAAa,IAAgB,GAAS,GAAK,MAAiB;AACxD,GAAU,KAAO,EAAI,SAAS,YAAY,EAAE;CAC5C,IAAM,IAAa,EAAI,YAAY,QAAQ,MAAM,EAAE,SAAS,sBAAsB;AAmBlF,CATI,KACA,EACI,EAAW,UAAU,KAAK,EAAW,GAAG,cAAc,GACtD,GACA,GACA,GACA,EAAW,GAAG,UACjB,EAEL,EAAM,GAAK,EACP,MAAM,GAAO,GAAG,GAAI,GAAM;AACtB,MAAI,EAAM,UACL,EAAM,MAAM,UAAU,gBACnB,EAAM,MAAM,MAAM,WAAW,QAAQ,KACzC,EAAM,MAAM,UAAU,EAAM,KAAK,OAAO;GAExC,IAAI,IAAU,GAAK,IAAY,EAAE;AACjC,QAAK,IAAM,KAAO,EAEd,CADA,IAAU,EAAQ,IACd,EAAQ,SAAS,EAAK,SACtB,EAAU,KAAK,EAAQ,OAAO,SAAS,EAAQ,KAAK,MAAM;AAIlE,SADA,EAAU,OAAO,IAAI,GAAG,EAAM,KAAK,MAAM,EACnC,EACF,GACA,EAAM,MAAM,OACZ,EAAU,KAAK,IAAI,EACnB,EAAW,GAAG,WACd,EAAiB,GAAK,cAAc,CACvC;;IAGZ,CAAC;GACH,EACC,KAAK,EAAW,iBAAoB,KACvC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getMainDefinition.js","names":[],"sources":["../../../../../../node_modules/@apollo/client/utilities/internal/getMainDefinition.js"],"sourcesContent":["import { newInvariantError } from \"@apollo/client/utilities/invariant\";\nimport { checkDocument } from \"./checkDocument.js\";\n/**\n * Returns the first operation definition from a GraphQL document. The function\n * prioritizes operation definitions over fragment definitions, which makes it\n * suitable for documents that may contain both. If no operation definition is\n * found, the first fragment definition will be returned. If no definitions are\n * found, an error is thrown.\n *\n * @remarks\n *\n * Use this function when you need to perform more advanced tasks with the main\n * definition AST node. If you want to determine when a document is a specific\n * operation type, prefer the `isQueryOperation`, `isMutationOperation`, and\n * `isSubscriptionOperation` utility functions instead.\n *\n * @param queryDoc - The GraphQL document to extract the definition from\n * @returns The main operation or fragment definition AST node\n *\n * @example\n *\n * ```ts\n * import { gql } from \"@apollo/client\";\n * import { getMainDefinition } from \"@apollo/client/utilities\";\n *\n * const query = gql`\n * query GetUser($id: ID!) {\n * user(id: $id) {\n * name\n * email\n * }\n * }\n * `;\n *\n * const definition = getMainDefinition(query);\n * ```\n *\n * @throws When the document contains no operation or fragment definitions\n */\nexport function getMainDefinition(queryDoc) {\n checkDocument(queryDoc);\n let fragmentDefinition;\n for (let definition of queryDoc.definitions) {\n if (definition.kind === \"OperationDefinition\") {\n return definition;\n }\n if (definition.kind === \"FragmentDefinition\" && !fragmentDefinition) {\n // we do this because we want to allow multiple fragment definitions\n // to precede an operation definition.\n fragmentDefinition = definition;\n }\n }\n if (fragmentDefinition) {\n return fragmentDefinition;\n }\n throw newInvariantError(12);\n}\n//# sourceMappingURL=getMainDefinition.js.map\n"],"x_google_ignoreList":[0],"mappings":";;;AAuCA,SAAgB,EAAkB,GAAU;AACxC,GAAc,EAAS;CACvB,IAAI;AACJ,MAAK,IAAI,KAAc,EAAS,aAAa;AACzC,MAAI,EAAW,SAAS,sBACpB,QAAO;AAEX,EAAI,EAAW,SAAS,wBAAwB,CAAC,MAG7C,IAAqB;;AAG7B,KAAI,EACA,QAAO;AAEX,OAAM,EAAkB,GAAG"}
|