@burdenoff/microfe-store 2026.626.1 → 2026.626.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"useStoreGraphQL.js","names":[],"sources":["../../src/hooks/useStoreGraphQL.ts"],"sourcesContent":["import { useState, useEffect, useCallback, useRef, useMemo } from 'react';\nimport { useApolloClient } from '@apollo/client/react';\nimport { useStore } from '../providers/StoreProvider';\nimport { useStoreGraphQLWithContext } from './useStoreGraphQLWithContext';\nimport {\n BrowseStoreDocument,\n StoreProductDetailsDocument,\n HomeGroupedProductsDocument,\n} from '../generated/global-operations';\nimport { type BrowseStoreInput, type StoreProductDetailsInput } from '../generated/global-types';\n\n// Local type definitions until schema is fully defined\ntype ProductType = 'APP' | 'TEMPLATE' | 'THEME' | 'INTEGRATION' | 'WIDGET' | 'DATASET';\ntype CreateReviewInput = { productId: string; rating: number; title?: string; comment?: string };\ntype UpdateReviewInput = { rating?: number; title?: string; comment?: string };\n\n// Import generated document nodes for operations extracted to .graphql files\nimport {\n FeaturedProductsDocument,\n SearchSuggestionsDocument,\n TrendingSearchesDocument,\n FilterOptionsDocument,\n CategoriesDocument,\n ProductReviewsDocument,\n UserReviewForProductDocument,\n MyEntitlementsDocument,\n CheckEntitlementDocument,\n WorkspaceStoreOrdersDocument,\n MyPublishedProductsDocument,\n DeveloperEarningsDocument,\n CreateReviewDocument,\n UpdateReviewDocument,\n DeleteReviewDocument,\n MarkReviewHelpfulDocument,\n} from '../generated/global-operations';\n\n// ============================================================================\n// Helper to get Apollo Client\n// ============================================================================\n\n/**\n * Hook to get the store Apollo client from the shell's GatewayRoute context.\n * The Store route is wrapped with <GatewayRoute gateway=\"global\"> in the app shell,\n * so useApolloClient() returns the global gateway client.\n */\nfunction useStoreClient() {\n return useApolloClient();\n}\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\ninterface StoreProduct {\n id: string;\n name: string;\n slug: string;\n type: string;\n nature: string;\n status: string;\n description?: string;\n pricingModel: string;\n price: number;\n currency: string;\n icon?: string;\n screenshots: string[];\n rating?: number;\n reviewCount: number;\n downloads: number;\n featured: boolean;\n category?: string;\n tags?: string[];\n publishedAt?: string;\n publisher?: {\n id: string;\n name: string;\n isVerified: boolean;\n logoUrl?: string;\n };\n}\n\ninterface BrowseStoreResult {\n products: StoreProduct[];\n totalCount: number;\n hasMore: boolean;\n nextCursor?: string;\n facets?: {\n types: { value: string; count: number }[];\n subTypes: { value: string; count: number }[];\n categories: { value: string; count: number }[];\n pricingModels: { value: string; count: number }[];\n licenses: { value: string; count: number }[];\n priceRange?: { min: number; max: number };\n ratingDistribution?: {\n fiveStars: number;\n fourStars: number;\n threeStars: number;\n twoStars: number;\n oneStar: number;\n };\n };\n}\n\ninterface ProductReview {\n id: string;\n productId: string;\n userId: string;\n rating: number;\n title?: string;\n comment?: string;\n status: string;\n helpful: number;\n createdAt: string;\n updatedAt: string;\n}\n\ninterface ProductCategory {\n id: string;\n name: string;\n slug: string;\n description?: string;\n icon?: string;\n parentId?: string;\n}\n\ninterface SearchSuggestion {\n term: string;\n type: string;\n count: number;\n highlight?: string;\n}\n\ninterface GroupedProducts {\n featured: StoreProduct[];\n mostDownloaded: StoreProduct[];\n recentlyAdded: StoreProduct[];\n freeItems: StoreProduct[];\n}\n\n// GraphQL Query Result Types\ninterface StoreProductDetailsData {\n storeProductDetails?: {\n product: StoreProduct;\n publisher?: {\n id: string;\n name: string;\n isVerified: boolean;\n logoUrl?: string;\n };\n relatedProducts?: StoreProduct[];\n reviews?: ProductReview[];\n } | null;\n}\n\ninterface FilterOptionsData {\n filterOptions?: {\n types: { value: string; count: number }[];\n subTypes: { value: string; count: number }[];\n categories: { value: string; count: number }[];\n pricingModels: { value: string; count: number }[];\n licenses: { value: string; count: number }[];\n priceRange?: { min: number; max: number };\n } | null;\n}\n\ninterface CheckEntitlementData {\n checkEntitlement?: {\n hasAccess: boolean;\n entitlement?: {\n id: string;\n productId: string;\n type: string;\n status: string;\n expiresAt?: string;\n };\n } | null;\n}\n\ninterface DeveloperEarningsData {\n developerEarnings?: {\n totalEarnings: number;\n pendingPayout: number;\n periodEarnings: number;\n currency: string;\n transactions?: Array<{\n id: string;\n amount: number;\n type: string;\n status: string;\n createdAt: string;\n }>;\n } | null;\n}\n\n// ============================================================================\n// Browse & Search Hooks\n// ============================================================================\n\n/**\n * Hook to browse/search store products with filters\n * Uses Apollo Client from context\n */\nexport function useBrowseStore(input: BrowseStoreInput = {}) {\n const client = useStoreClient();\n const [products, setProducts] = useState<StoreProduct[]>([]);\n const [totalCount, setTotalCount] = useState(0);\n const [hasMore, setHasMore] = useState(false);\n const [facets, setFacets] = useState<BrowseStoreResult['facets']>(undefined);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n // Stringify input to use as stable dependency\n const inputKey = JSON.stringify(input);\n\n const fetchData = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<{ browseStore: BrowseStoreResult }>({\n query: BrowseStoreDocument,\n variables: { input: JSON.parse(inputKey) },\n fetchPolicy: 'network-only',\n });\n setProducts(result.data?.browseStore?.products ?? []);\n setTotalCount(result.data?.browseStore?.totalCount ?? 0);\n setHasMore(result.data?.browseStore?.hasMore ?? false);\n setFacets(result.data?.browseStore?.facets);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [client, inputKey]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n products,\n totalCount,\n hasMore,\n facets,\n loading,\n error,\n refetch: fetchData,\n };\n}\n\n/**\n * Hook to browse/search store products with organization context.\n * Uses organization-aware GraphQL client with automatic headers.\n * Automatically applies defaultCompatibleWith from store context\n * to the filter if not already specified in the input.\n */\nexport function useBrowseStoreWithContext(\n input: BrowseStoreInput = {},\n options?: { skip?: boolean }\n) {\n const { query: queryWithContext, hasOrganizationContext } = useStoreGraphQLWithContext();\n const globalClient = useApolloClient();\n const { defaultCompatibleWith } = useStore();\n const [allProducts, setAllProducts] = useState<StoreProduct[]>([]);\n const [totalCount, setTotalCount] = useState(0);\n const [hasMore, setHasMore] = useState(false);\n const [facets, setFacets] = useState<BrowseStoreResult['facets']>(undefined);\n const [loading, setLoading] = useState(!options?.skip);\n const [error, setError] = useState<Error | null>(null);\n const [currentOffset, setCurrentOffset] = useState(input.pagination?.offset ?? 0);\n\n const skip = options?.skip;\n\n // Merge defaultCompatibleWith into the input filter if not already set\n const mergedInput = useMemo(() => {\n if (!defaultCompatibleWith) return input;\n const merged = { ...input };\n if (merged.filter) {\n merged.filter = { ...merged.filter };\n if (!merged.filter.compatibleWith) {\n merged.filter.compatibleWith = defaultCompatibleWith;\n }\n } else {\n merged.filter = { compatibleWith: defaultCompatibleWith };\n }\n return merged;\n }, [input, defaultCompatibleWith]);\n\n // Stringify only filter/sort/type parts (NOT offset) as stable dependency\n // so changing offset for loadMore doesn't retrigger the effect\n const filterKey = useMemo(() => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { pagination, ...rest } = mergedInput;\n return JSON.stringify(rest);\n }, [mergedInput]);\n\n const pageLimit = input.pagination?.limit ?? 30;\n\n const fetchData = useCallback(\n async (fetchOffset: number, append: boolean) => {\n if (skip) {\n setLoading(false);\n return;\n }\n setLoading(true);\n setError(null);\n try {\n const queryInput: BrowseStoreInput = {\n ...(JSON.parse(filterKey) as BrowseStoreInput),\n pagination: { ...mergedInput.pagination, limit: pageLimit, offset: fetchOffset },\n };\n\n let result;\n\n if (hasOrganizationContext) {\n // Use organization-aware query\n result = (await queryWithContext({\n query: BrowseStoreDocument,\n variables: { input: queryInput },\n fetchPolicy: 'network-only',\n })) as { data?: { browseStore: BrowseStoreResult } };\n } else {\n // Fallback to global client without organization context\n result = await globalClient.query<{ browseStore: BrowseStoreResult }>({\n query: BrowseStoreDocument,\n variables: { input: queryInput },\n fetchPolicy: 'network-only',\n });\n }\n\n const fetched = result.data?.browseStore?.products ?? [];\n if (append) {\n setAllProducts((prev) => [...prev, ...fetched]);\n } else {\n setAllProducts(fetched);\n }\n setTotalCount(result.data?.browseStore?.totalCount ?? 0);\n setHasMore(result.data?.browseStore?.hasMore ?? false);\n setFacets(result.data?.browseStore?.facets);\n setCurrentOffset(fetchOffset + fetched.length);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n },\n [\n queryWithContext,\n globalClient,\n hasOrganizationContext,\n filterKey,\n skip,\n pageLimit,\n mergedInput.pagination,\n ]\n );\n\n // Re-fetch from offset 0 whenever filters/sort change. fetchData and pagination\n // offset are intentionally read via refs to avoid refetch loops on stable changes.\n const fetchDataRef = useRef(fetchData);\n fetchDataRef.current = fetchData;\n const offsetRef = useRef(input.pagination?.offset ?? 0);\n offsetRef.current = input.pagination?.offset ?? 0;\n useEffect(() => {\n void fetchDataRef.current(offsetRef.current, false);\n }, [filterKey, skip]);\n\n const loadMore = useCallback(() => {\n if (!hasMore || loading) return;\n void fetchData(currentOffset, true);\n }, [fetchData, hasMore, loading, currentOffset]);\n\n return {\n products: allProducts,\n totalCount,\n hasMore,\n facets,\n loading,\n error,\n refetch: () => fetchData(input.pagination?.offset ?? 0, false),\n loadMore,\n };\n}\n\n/**\n * Lazy hook to browse store on demand\n */\nexport function useLazyBrowseStore() {\n const client = useStoreClient();\n const [products, setProducts] = useState<StoreProduct[]>([]);\n const [totalCount, setTotalCount] = useState(0);\n const [hasMore, setHasMore] = useState(false);\n const [facets, setFacets] = useState<BrowseStoreResult['facets']>(undefined);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const browseStore = useCallback(\n async (input: BrowseStoreInput = {}) => {\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<{ browseStore: BrowseStoreResult }>({\n query: BrowseStoreDocument,\n variables: { input },\n fetchPolicy: 'network-only',\n });\n const data = result.data?.browseStore;\n setProducts(data?.products ?? []);\n setTotalCount(data?.totalCount ?? 0);\n setHasMore(data?.hasMore ?? false);\n setFacets(data?.facets);\n return data;\n } catch (err) {\n setError(err as Error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [client]\n );\n\n return {\n browseStore,\n products,\n totalCount,\n hasMore,\n facets,\n loading,\n error,\n };\n}\n\n/**\n * Hook to fetch product details for product page\n */\nexport function useStoreProductDetails(input: StoreProductDetailsInput) {\n const { query: queryWithContext, hasOrganizationContext } = useStoreGraphQLWithContext();\n const globalClient = useApolloClient();\n const [data, setData] = useState<unknown>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const shouldSkip = !input.id && !input.slug;\n\n // Stringify input to use as stable dependency (prevents infinite loops)\n const inputKey = JSON.stringify(input);\n\n // Track if fetch has been attempted for this input\n const fetchedRef = useRef<string | null>(null);\n\n const fetchData = useCallback(async () => {\n if (shouldSkip) {\n setLoading(false);\n return;\n }\n\n // Skip if already fetched for this input\n if (fetchedRef.current === inputKey) {\n return;\n }\n fetchedRef.current = inputKey;\n\n setLoading(true);\n setError(null);\n try {\n const result = hasOrganizationContext\n ? ((await queryWithContext({\n query: StoreProductDetailsDocument,\n variables: { input: JSON.parse(inputKey) },\n fetchPolicy: 'network-only',\n })) as { data?: StoreProductDetailsData })\n : await globalClient.query<StoreProductDetailsData>({\n query: StoreProductDetailsDocument,\n variables: { input: JSON.parse(inputKey) },\n fetchPolicy: 'network-only',\n });\n setData(result.data?.storeProductDetails ?? null);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [globalClient, hasOrganizationContext, inputKey, queryWithContext, shouldSkip]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n data,\n loading,\n error,\n refetch: () => {\n fetchedRef.current = null; // Reset to allow refetch\n return fetchData();\n },\n };\n}\n\n/**\n * Lazy hook to fetch product details on demand\n */\nexport function useLazyStoreProductDetails() {\n const { query: queryWithContext, hasOrganizationContext } = useStoreGraphQLWithContext();\n const globalClient = useApolloClient();\n const [data, setData] = useState<unknown>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const getProductDetails = useCallback(\n async (input: StoreProductDetailsInput) => {\n setLoading(true);\n setError(null);\n try {\n const result = hasOrganizationContext\n ? ((await queryWithContext({\n query: StoreProductDetailsDocument,\n variables: { input },\n })) as { data?: StoreProductDetailsData })\n : await globalClient.query<StoreProductDetailsData>({\n query: StoreProductDetailsDocument,\n variables: { input },\n });\n const details = result.data?.storeProductDetails ?? null;\n setData(details);\n return details;\n } catch (err) {\n setError(err as Error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [globalClient, hasOrganizationContext, queryWithContext]\n );\n\n return {\n getProductDetails,\n data,\n loading,\n error,\n };\n}\n\n/**\n * Hook to fetch grouped products for homepage.\n */\nexport function useHomeGroupedProducts(options?: { skip?: boolean }) {\n const client = useStoreClient();\n const { defaultCompatibleWith } = useStore();\n const [data, setData] = useState<GroupedProducts | null>(null);\n const [loading, setLoading] = useState(!options?.skip);\n const [error, setError] = useState<Error | null>(null);\n\n const skip = options?.skip;\n\n const fetchData = useCallback(async () => {\n if (skip) {\n setLoading(false);\n return;\n }\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<{ homeGroupedProducts: GroupedProducts }>({\n query: HomeGroupedProductsDocument,\n variables: { compatibleWith: defaultCompatibleWith ?? null },\n fetchPolicy: 'cache-first',\n });\n setData(result.data?.homeGroupedProducts ?? null);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [client, defaultCompatibleWith, skip]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n data,\n featured: data?.featured ?? [],\n mostDownloaded: data?.mostDownloaded ?? [],\n recentlyAdded: data?.recentlyAdded ?? [],\n freeItems: data?.freeItems ?? [],\n loading,\n error,\n refetch: fetchData,\n };\n}\n\n/**\n * Hook to fetch featured products\n */\nexport function useFeaturedProducts(limit?: number) {\n const client = useStoreClient();\n const [products, setProducts] = useState<StoreProduct[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchData = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<{ featuredProducts: StoreProduct[] }>({\n query: FeaturedProductsDocument,\n variables: { limit },\n fetchPolicy: 'cache-first',\n });\n setProducts(result.data?.featuredProducts ?? []);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [client, limit]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n products,\n loading,\n error,\n refetch: fetchData,\n };\n}\n\n/**\n * Hook to fetch search suggestions for autocomplete\n */\nexport function useSearchSuggestions(\n query: string,\n options?: { limit?: number; types?: string[] }\n) {\n const client = useStoreClient();\n const [suggestions, setSuggestions] = useState<SearchSuggestion[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const shouldSkip = query.length < 2;\n\n const fetchData = useCallback(async () => {\n if (shouldSkip) {\n setSuggestions([]);\n return;\n }\n\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<{ searchSuggestions: SearchSuggestion[] }>({\n query: SearchSuggestionsDocument,\n variables: { query, limit: options?.limit, types: options?.types },\n fetchPolicy: 'network-only',\n });\n setSuggestions(result.data?.searchSuggestions ?? []);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [client, query, options?.limit, options?.types, shouldSkip]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n suggestions,\n loading,\n error,\n refetch: fetchData,\n };\n}\n\n/**\n * Lazy hook to fetch search suggestions on demand\n */\nexport function useLazySearchSuggestions() {\n const client = useStoreClient();\n const [suggestions, setSuggestions] = useState<SearchSuggestion[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const getSuggestions = useCallback(\n async (query: string, options?: { limit?: number; types?: string[] }) => {\n if (query.length < 2) {\n setSuggestions([]);\n return [];\n }\n\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<{ searchSuggestions: SearchSuggestion[] }>({\n query: SearchSuggestionsDocument,\n variables: { query, limit: options?.limit, types: options?.types },\n fetchPolicy: 'network-only',\n });\n const data = result.data?.searchSuggestions ?? [];\n setSuggestions(data);\n return data;\n } catch (err) {\n setError(err as Error);\n return [];\n } finally {\n setLoading(false);\n }\n },\n [client]\n );\n\n return {\n getSuggestions,\n suggestions,\n loading,\n error,\n };\n}\n\n/**\n * Hook to fetch trending search terms\n */\nexport function useTrendingSearches(options?: { limit?: number; type?: ProductType }) {\n const client = useStoreClient();\n const [terms, setTerms] = useState<string[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchData = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<{ trendingSearches: string[] }>({\n query: TrendingSearchesDocument,\n variables: { limit: options?.limit, type: options?.type },\n fetchPolicy: 'cache-first',\n });\n setTerms(result.data?.trendingSearches ?? []);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [client, options?.limit, options?.type]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n terms,\n loading,\n error,\n refetch: fetchData,\n };\n}\n\n/**\n * Hook to fetch filter options for dropdowns\n */\nexport function useFilterOptions(options?: { type?: ProductType; withProducts?: boolean }) {\n const client = useStoreClient();\n const [filterOptions, setFilterOptions] = useState<unknown>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchData = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<FilterOptionsData>({\n query: FilterOptionsDocument,\n variables: { type: options?.type, withProducts: options?.withProducts },\n fetchPolicy: 'cache-first',\n });\n setFilterOptions(result.data?.filterOptions ?? null);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [client, options?.type, options?.withProducts]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n filterOptions,\n loading,\n error,\n refetch: fetchData,\n };\n}\n\n// ============================================================================\n// Category Hooks\n// ============================================================================\n\n/**\n * Hook to fetch all categories\n */\nexport function useCategories() {\n const client = useStoreClient();\n const [categories, setCategories] = useState<ProductCategory[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchData = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<{ categories: ProductCategory[] }>({\n query: CategoriesDocument,\n fetchPolicy: 'cache-first',\n });\n setCategories(result.data?.categories ?? []);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [client]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n categories,\n loading,\n error,\n refetch: fetchData,\n };\n}\n\n// ============================================================================\n// Review Hooks\n// ============================================================================\n\n/**\n * Hook to fetch reviews for a product\n */\nexport function useProductReviews(productId: string, options?: { status?: string }) {\n const client = useStoreClient();\n const [reviews, setReviews] = useState<ProductReview[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchData = useCallback(async () => {\n if (!productId) {\n setLoading(false);\n return;\n }\n\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<{ productReviews: ProductReview[] }>({\n query: ProductReviewsDocument,\n variables: { productId, status: options?.status },\n fetchPolicy: 'cache-first',\n });\n setReviews(result.data?.productReviews ?? []);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [client, productId, options?.status]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n reviews,\n loading,\n error,\n refetch: fetchData,\n };\n}\n\n/**\n * Hook to fetch current user's review for a product\n */\nexport function useUserReviewForProduct(productId: string) {\n const client = useStoreClient();\n const [review, setReview] = useState<ProductReview | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchData = useCallback(async () => {\n if (!productId) {\n setLoading(false);\n return;\n }\n\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<{ userReviewForProduct: ProductReview | null }>({\n query: UserReviewForProductDocument,\n variables: { productId },\n fetchPolicy: 'network-only',\n });\n setReview(result.data?.userReviewForProduct ?? null);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [client, productId]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n review,\n loading,\n error,\n refetch: fetchData,\n };\n}\n\n/**\n * Hook to create a review\n */\nexport function useCreateReview() {\n const client = useStoreClient();\n const [review, setReview] = useState<ProductReview | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const createReview = useCallback(\n async (input: CreateReviewInput) => {\n setLoading(true);\n setError(null);\n try {\n const result = await client.mutate<{ createReview: ProductReview }>({\n mutation: CreateReviewDocument,\n variables: { input },\n });\n const data = result.data?.createReview ?? null;\n setReview(data);\n return data;\n } catch (err) {\n setError(err as Error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [client]\n );\n\n return {\n createReview,\n review,\n loading,\n error,\n };\n}\n\n/**\n * Hook to update a review\n */\nexport function useUpdateReview() {\n const client = useStoreClient();\n const [review, setReview] = useState<ProductReview | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const updateReview = useCallback(\n async (id: string, input: UpdateReviewInput) => {\n setLoading(true);\n setError(null);\n try {\n const result = await client.mutate<{ updateReview: ProductReview }>({\n mutation: UpdateReviewDocument,\n variables: { id, input },\n });\n const data = result.data?.updateReview ?? null;\n setReview(data);\n return data;\n } catch (err) {\n setError(err as Error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [client]\n );\n\n return {\n updateReview,\n review,\n loading,\n error,\n };\n}\n\n/**\n * Hook to delete a review\n */\nexport function useDeleteReview() {\n const client = useStoreClient();\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const deleteReview = useCallback(\n async (id: string) => {\n setLoading(true);\n setError(null);\n try {\n const result = await client.mutate<{ deleteReview: boolean }>({\n mutation: DeleteReviewDocument,\n variables: { id },\n });\n return result.data?.deleteReview ?? false;\n } catch (err) {\n setError(err as Error);\n return false;\n } finally {\n setLoading(false);\n }\n },\n [client]\n );\n\n return {\n deleteReview,\n loading,\n error,\n };\n}\n\n/**\n * Hook to mark review as helpful\n */\nexport function useMarkReviewHelpful() {\n const client = useStoreClient();\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const markHelpful = useCallback(\n async (id: string) => {\n setLoading(true);\n setError(null);\n try {\n const result = await client.mutate<{ markReviewHelpful: { id: string; helpful: number } }>({\n mutation: MarkReviewHelpfulDocument,\n variables: { id },\n });\n return result.data?.markReviewHelpful ?? null;\n } catch (err) {\n setError(err as Error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [client]\n );\n\n return {\n markHelpful,\n loading,\n error,\n };\n}\n\n// ============================================================================\n// Entitlement Hooks\n// ============================================================================\n\n/**\n * Hook to fetch current user's entitlements\n */\nexport function useMyEntitlements() {\n const { query: queryWithContext, hasOrganizationContext } = useStoreGraphQLWithContext();\n const globalClient = useApolloClient();\n const PAGE_SIZE = 20;\n const [allEntitlements, setAllEntitlements] = useState<unknown[]>([]);\n const [hasMore, setHasMore] = useState(false);\n const [currentOffset, setCurrentOffset] = useState(0);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchData = useCallback(\n async (fetchOffset = 0, append = false) => {\n setLoading(true);\n setError(null);\n try {\n const variables = { limit: PAGE_SIZE, offset: fetchOffset };\n const result = hasOrganizationContext\n ? ((await queryWithContext({\n query: MyEntitlementsDocument,\n variables,\n fetchPolicy: 'network-only',\n })) as { data?: { myEntitlements: unknown[] } })\n : await globalClient.query<{ myEntitlements: unknown[] }>({\n query: MyEntitlementsDocument,\n variables,\n fetchPolicy: 'network-only',\n });\n const fetched = result.data?.myEntitlements ?? [];\n if (append) {\n setAllEntitlements((prev) => [...prev, ...fetched]);\n } else {\n setAllEntitlements(fetched);\n }\n setHasMore(fetched.length === PAGE_SIZE);\n setCurrentOffset(fetchOffset);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n },\n [globalClient, hasOrganizationContext, queryWithContext]\n );\n\n useEffect(() => {\n fetchData(0);\n }, [fetchData]);\n\n const loadMore = useCallback(() => {\n if (!hasMore || loading) return;\n fetchData(currentOffset + PAGE_SIZE, true);\n }, [fetchData, hasMore, loading, currentOffset]);\n\n return {\n entitlements: allEntitlements,\n hasMore,\n loading,\n error,\n refetch: () => fetchData(0),\n loadMore,\n };\n}\n\n/**\n * Hook to check entitlement for a product\n */\nexport function useCheckEntitlement(productId: string) {\n const client = useStoreClient();\n const [entitlement, setEntitlement] = useState<unknown>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchData = useCallback(async () => {\n if (!productId) {\n setLoading(false);\n return;\n }\n\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<CheckEntitlementData>({\n query: CheckEntitlementDocument,\n variables: { productId },\n fetchPolicy: 'network-only',\n });\n setEntitlement(result.data?.checkEntitlement ?? null);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [client, productId]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n entitlement,\n loading,\n error,\n refetch: fetchData,\n };\n}\n\n// ============================================================================\n// Order Hooks\n// ============================================================================\n\n/**\n * Hook to fetch workspace store orders\n */\nexport function useWorkspaceStoreOrders(\n billingAccountId: string,\n page: number,\n limit: number,\n options?: { status?: string; search?: string }\n) {\n const client = useStoreClient();\n const [orders, setOrders] = useState<unknown[]>([]);\n const [total, setTotal] = useState(0);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchData = useCallback(async () => {\n if (!billingAccountId) {\n setLoading(false);\n return;\n }\n\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<{\n workspaceStoreOrders: { total: number; orders: unknown[] };\n }>({\n query: WorkspaceStoreOrdersDocument,\n variables: {\n billingAccountId,\n page,\n limit,\n status: options?.status,\n search: options?.search,\n },\n fetchPolicy: 'network-only',\n });\n setOrders(result.data?.workspaceStoreOrders?.orders ?? []);\n setTotal(result.data?.workspaceStoreOrders?.total ?? 0);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [client, billingAccountId, page, limit, options?.status, options?.search]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n orders,\n total,\n loading,\n error,\n refetch: fetchData,\n };\n}\n\n// ============================================================================\n// Publisher Hooks\n// ============================================================================\n\n/**\n * Hook to fetch publisher's products\n */\nexport function useMyPublishedProducts() {\n const client = useStoreClient();\n const [allProducts, setAllProducts] = useState<StoreProduct[]>([]);\n const [hasMore, setHasMore] = useState(false);\n const [currentOffset, setCurrentOffset] = useState(0);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const PAGE_SIZE = 20;\n\n const fetchData = useCallback(\n async (fetchOffset = 0, append = false) => {\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<{ publishedProducts: StoreProduct[] }>({\n query: MyPublishedProductsDocument,\n variables: { limit: PAGE_SIZE, offset: fetchOffset },\n fetchPolicy: 'network-only',\n });\n const fetched = result.data?.publishedProducts ?? [];\n if (append) {\n setAllProducts((prev) => [...prev, ...fetched]);\n } else {\n setAllProducts(fetched);\n }\n setHasMore(fetched.length === PAGE_SIZE);\n setCurrentOffset(fetchOffset + fetched.length);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n },\n [client]\n );\n\n const loadMore = useCallback(() => {\n if (!hasMore || loading) return;\n void fetchData(currentOffset, true);\n }, [fetchData, hasMore, loading, currentOffset]);\n\n useEffect(() => {\n void fetchData(0, false);\n }, [fetchData]);\n\n return {\n products: allProducts,\n hasMore,\n loading,\n error,\n refetch: () => fetchData(0, false),\n loadMore,\n };\n}\n\n/**\n * Hook to fetch developer earnings\n */\nexport function useDeveloperEarnings(options?: {\n period?: string;\n startDate?: string;\n endDate?: string;\n}) {\n const { query: queryWithContext, hasOrganizationContext } = useStoreGraphQLWithContext();\n const globalClient = useApolloClient();\n const [earnings, setEarnings] = useState<unknown>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchData = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const result = hasOrganizationContext\n ? ((await queryWithContext({\n query: DeveloperEarningsDocument,\n variables: { input: options },\n fetchPolicy: 'network-only',\n })) as { data?: DeveloperEarningsData })\n : await globalClient.query<DeveloperEarningsData>({\n query: DeveloperEarningsDocument,\n variables: { input: options },\n fetchPolicy: 'network-only',\n });\n setEarnings(result.data?.developerEarnings ?? null);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [globalClient, hasOrganizationContext, options, queryWithContext]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n earnings,\n loading,\n error,\n refetch: fetchData,\n };\n}\n\n// ============================================================================\n// Re-export types for convenience\n// ============================================================================\n\nexport type {\n BrowseStoreInput,\n StoreProductDetailsInput,\n ProductType,\n CreateReviewInput,\n UpdateReviewInput,\n StoreProduct,\n ProductReview,\n ProductCategory,\n SearchSuggestion,\n GroupedProducts,\n BrowseStoreResult,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"useStoreGraphQL.js","names":[],"sources":["../../src/hooks/useStoreGraphQL.ts"],"sourcesContent":["import { useState, useEffect, useCallback, useRef, useMemo } from 'react';\nimport { useApolloClient } from '@apollo/client/react';\nimport { useStore } from '../providers/StoreProvider';\nimport { useStoreGraphQLWithContext } from './useStoreGraphQLWithContext';\nimport {\n BrowseStoreDocument,\n StoreProductDetailsDocument,\n HomeGroupedProductsDocument,\n} from '../generated/global-operations';\nimport { type BrowseStoreInput, type StoreProductDetailsInput } from '../generated/global-types';\n\n// Local type definitions until schema is fully defined\ntype ProductType = 'APP' | 'TEMPLATE' | 'THEME' | 'INTEGRATION' | 'WIDGET' | 'DATASET';\ntype CreateReviewInput = { productId: string; rating: number; title?: string; comment?: string };\ntype UpdateReviewInput = { rating?: number; title?: string; comment?: string };\n\n// Import generated document nodes for operations extracted to .graphql files\nimport {\n FeaturedProductsDocument,\n SearchSuggestionsDocument,\n TrendingSearchesDocument,\n FilterOptionsDocument,\n CategoriesDocument,\n ProductReviewsDocument,\n UserReviewForProductDocument,\n MyEntitlementsDocument,\n CheckEntitlementDocument,\n WorkspaceStoreOrdersDocument,\n MyPublishedProductsDocument,\n DeveloperEarningsDocument,\n CreateReviewDocument,\n UpdateReviewDocument,\n DeleteReviewDocument,\n MarkReviewHelpfulDocument,\n} from '../generated/global-operations';\n\n// ============================================================================\n// Helper to get Apollo Client\n// ============================================================================\n\n/**\n * Hook to get the store Apollo client from the shell's GatewayRoute context.\n * The Store route is wrapped with <GatewayRoute gateway=\"global\"> in the app shell,\n * so useApolloClient() returns the global gateway client.\n */\nfunction useStoreClient() {\n return useApolloClient();\n}\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\ninterface StoreProduct {\n id: string;\n name: string;\n slug: string;\n type: string;\n nature: string;\n status: string;\n description?: string;\n pricingModel: string;\n price: number;\n currency: string;\n icon?: string;\n screenshots: string[];\n rating?: number;\n reviewCount: number;\n downloads: number;\n featured: boolean;\n category?: string;\n tags?: string[];\n publishedAt?: string;\n publisher?: {\n id: string;\n name: string;\n isVerified: boolean;\n logoUrl?: string;\n };\n}\n\ninterface BrowseStoreResult {\n products: StoreProduct[];\n totalCount: number;\n hasMore: boolean;\n nextCursor?: string;\n facets?: {\n types: { value: string; count: number }[];\n subTypes: { value: string; count: number }[];\n categories: { value: string; count: number }[];\n pricingModels: { value: string; count: number }[];\n licenses: { value: string; count: number }[];\n priceRange?: { min: number; max: number };\n ratingDistribution?: {\n fiveStars: number;\n fourStars: number;\n threeStars: number;\n twoStars: number;\n oneStar: number;\n };\n };\n}\n\ninterface ProductReview {\n id: string;\n productId: string;\n userId: string;\n rating: number;\n title?: string;\n comment?: string;\n status: string;\n helpful: number;\n createdAt: string;\n updatedAt: string;\n}\n\ninterface ProductCategory {\n id: string;\n name: string;\n slug: string;\n description?: string;\n icon?: string;\n parentId?: string;\n}\n\ninterface SearchSuggestion {\n term: string;\n type: string;\n count: number;\n highlight?: string;\n}\n\ninterface GroupedProducts {\n featured: StoreProduct[];\n mostDownloaded: StoreProduct[];\n recentlyAdded: StoreProduct[];\n freeItems: StoreProduct[];\n}\n\n// GraphQL Query Result Types\ninterface StoreProductDetailsData {\n storeProductDetails?: {\n product: StoreProduct;\n publisher?: {\n id: string;\n name: string;\n isVerified: boolean;\n logoUrl?: string;\n };\n relatedProducts?: StoreProduct[];\n reviews?: ProductReview[];\n } | null;\n}\n\ninterface FilterOptionsData {\n filterOptions?: {\n types: { value: string; count: number }[];\n subTypes: { value: string; count: number }[];\n categories: { value: string; count: number }[];\n pricingModels: { value: string; count: number }[];\n licenses: { value: string; count: number }[];\n priceRange?: { min: number; max: number };\n } | null;\n}\n\ninterface CheckEntitlementData {\n checkEntitlement?: {\n hasAccess: boolean;\n entitlement?: {\n id: string;\n productId: string;\n type: string;\n status: string;\n expiresAt?: string;\n };\n } | null;\n}\n\ninterface DeveloperEarningsData {\n developerEarnings?: {\n totalEarnings: number;\n pendingPayout: number;\n periodEarnings: number;\n currency: string;\n transactions?: Array<{\n id: string;\n amount: number;\n type: string;\n status: string;\n createdAt: string;\n }>;\n } | null;\n}\n\n// ============================================================================\n// Browse & Search Hooks\n// ============================================================================\n\n/**\n * Hook to browse/search store products with filters\n * Uses Apollo Client from context\n */\nexport function useBrowseStore(input: BrowseStoreInput = {}) {\n const client = useStoreClient();\n const [products, setProducts] = useState<StoreProduct[]>([]);\n const [totalCount, setTotalCount] = useState(0);\n const [hasMore, setHasMore] = useState(false);\n const [facets, setFacets] = useState<BrowseStoreResult['facets']>(undefined);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n // Stringify input to use as stable dependency\n const inputKey = JSON.stringify(input);\n\n const fetchData = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<{ browseStore: BrowseStoreResult }>({\n query: BrowseStoreDocument,\n variables: { input: JSON.parse(inputKey) },\n fetchPolicy: 'network-only',\n });\n setProducts(result.data?.browseStore?.products ?? []);\n setTotalCount(result.data?.browseStore?.totalCount ?? 0);\n setHasMore(result.data?.browseStore?.hasMore ?? false);\n setFacets(result.data?.browseStore?.facets);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [client, inputKey]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n products,\n totalCount,\n hasMore,\n facets,\n loading,\n error,\n refetch: fetchData,\n };\n}\n\n/**\n * Hook to browse/search store products with organization context.\n * Uses organization-aware GraphQL client with automatic headers.\n * Automatically applies defaultCompatibleWith from store context\n * to the filter if not already specified in the input.\n */\nexport function useBrowseStoreWithContext(\n input: BrowseStoreInput = {},\n options?: { skip?: boolean }\n) {\n const { query: queryWithContext, hasOrganizationContext } = useStoreGraphQLWithContext();\n const globalClient = useApolloClient();\n const { defaultCompatibleWith } = useStore();\n const [allProducts, setAllProducts] = useState<StoreProduct[]>([]);\n const [totalCount, setTotalCount] = useState(0);\n const [hasMore, setHasMore] = useState(false);\n const [facets, setFacets] = useState<BrowseStoreResult['facets']>(undefined);\n const [loading, setLoading] = useState(!options?.skip);\n const [error, setError] = useState<Error | null>(null);\n const [currentOffset, setCurrentOffset] = useState(input.pagination?.offset ?? 0);\n\n const skip = options?.skip;\n\n // Merge defaultCompatibleWith into the input filter if not already set\n const mergedInput = useMemo(() => {\n if (!defaultCompatibleWith) return input;\n const merged = { ...input };\n if (merged.filter) {\n merged.filter = { ...merged.filter };\n if (!merged.filter.compatibleWith) {\n merged.filter.compatibleWith = defaultCompatibleWith;\n }\n } else {\n merged.filter = { compatibleWith: defaultCompatibleWith };\n }\n return merged;\n }, [input, defaultCompatibleWith]);\n\n // Stringify only filter/sort/type parts (NOT offset) as stable dependency\n // so changing offset for loadMore doesn't retrigger the effect\n const filterKey = useMemo(() => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { pagination, ...rest } = mergedInput;\n return JSON.stringify(rest);\n }, [mergedInput]);\n\n const pageLimit = input.pagination?.limit ?? 30;\n\n const fetchData = useCallback(\n async (fetchOffset: number, append: boolean) => {\n if (skip) {\n setLoading(false);\n return;\n }\n setLoading(true);\n setError(null);\n try {\n const queryInput: BrowseStoreInput = {\n ...(JSON.parse(filterKey) as BrowseStoreInput),\n pagination: { ...mergedInput.pagination, limit: pageLimit, offset: fetchOffset },\n };\n\n let result;\n\n if (hasOrganizationContext) {\n // Use organization-aware query\n result = (await queryWithContext({\n query: BrowseStoreDocument,\n variables: { input: queryInput },\n fetchPolicy: 'network-only',\n })) as { data?: { browseStore: BrowseStoreResult } };\n } else {\n // Fallback to global client without organization context\n result = await globalClient.query<{ browseStore: BrowseStoreResult }>({\n query: BrowseStoreDocument,\n variables: { input: queryInput },\n fetchPolicy: 'network-only',\n });\n }\n\n const fetched = result.data?.browseStore?.products ?? [];\n if (append) {\n setAllProducts((prev) => [...prev, ...fetched]);\n } else {\n setAllProducts(fetched);\n }\n setTotalCount(result.data?.browseStore?.totalCount ?? 0);\n setHasMore(result.data?.browseStore?.hasMore ?? false);\n setFacets(result.data?.browseStore?.facets);\n setCurrentOffset(fetchOffset + fetched.length);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n },\n [\n queryWithContext,\n globalClient,\n hasOrganizationContext,\n filterKey,\n skip,\n pageLimit,\n mergedInput.pagination,\n ]\n );\n\n // Re-fetch from offset 0 whenever filters/sort change. fetchData and pagination\n // offset are intentionally read via refs to avoid refetch loops on stable changes.\n const fetchDataRef = useRef(fetchData);\n fetchDataRef.current = fetchData;\n const offsetRef = useRef(input.pagination?.offset ?? 0);\n offsetRef.current = input.pagination?.offset ?? 0;\n useEffect(() => {\n void fetchDataRef.current(offsetRef.current, false);\n }, [filterKey, skip]);\n\n const loadMore = useCallback(() => {\n if (!hasMore || loading) return;\n void fetchData(currentOffset, true);\n }, [fetchData, hasMore, loading, currentOffset]);\n\n return {\n products: allProducts,\n totalCount,\n hasMore,\n facets,\n loading,\n error,\n refetch: () => fetchData(input.pagination?.offset ?? 0, false),\n loadMore,\n };\n}\n\n/**\n * Lazy hook to browse store on demand\n */\nexport function useLazyBrowseStore() {\n const client = useStoreClient();\n const [products, setProducts] = useState<StoreProduct[]>([]);\n const [totalCount, setTotalCount] = useState(0);\n const [hasMore, setHasMore] = useState(false);\n const [facets, setFacets] = useState<BrowseStoreResult['facets']>(undefined);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const browseStore = useCallback(\n async (input: BrowseStoreInput = {}) => {\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<{ browseStore: BrowseStoreResult }>({\n query: BrowseStoreDocument,\n variables: { input },\n fetchPolicy: 'network-only',\n });\n const data = result.data?.browseStore;\n setProducts(data?.products ?? []);\n setTotalCount(data?.totalCount ?? 0);\n setHasMore(data?.hasMore ?? false);\n setFacets(data?.facets);\n return data;\n } catch (err) {\n setError(err as Error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [client]\n );\n\n return {\n browseStore,\n products,\n totalCount,\n hasMore,\n facets,\n loading,\n error,\n };\n}\n\n/**\n * Hook to fetch product details for product page\n */\nexport function useStoreProductDetails(input: StoreProductDetailsInput) {\n const { query: queryWithContext, hasOrganizationContext } = useStoreGraphQLWithContext();\n const globalClient = useApolloClient();\n const [data, setData] = useState<unknown>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const shouldSkip = !input.id && !input.slug;\n\n // Stringify input to use as stable dependency (prevents infinite loops)\n const inputKey = JSON.stringify(input);\n\n // Track if fetch has been attempted for this input\n const fetchedRef = useRef<string | null>(null);\n\n const fetchData = useCallback(async () => {\n if (shouldSkip) {\n setLoading(false);\n return;\n }\n\n // Skip if already fetched for this input\n if (fetchedRef.current === inputKey) {\n return;\n }\n fetchedRef.current = inputKey;\n\n setLoading(true);\n setError(null);\n try {\n const result = hasOrganizationContext\n ? ((await queryWithContext({\n query: StoreProductDetailsDocument,\n variables: { input: JSON.parse(inputKey) },\n fetchPolicy: 'network-only',\n })) as { data?: StoreProductDetailsData })\n : await globalClient.query<StoreProductDetailsData>({\n query: StoreProductDetailsDocument,\n variables: { input: JSON.parse(inputKey) },\n fetchPolicy: 'network-only',\n });\n setData(result.data?.storeProductDetails ?? null);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [globalClient, hasOrganizationContext, inputKey, queryWithContext, shouldSkip]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n data,\n loading,\n error,\n refetch: () => {\n fetchedRef.current = null; // Reset to allow refetch\n return fetchData();\n },\n };\n}\n\n/**\n * Lazy hook to fetch product details on demand\n */\nexport function useLazyStoreProductDetails() {\n const { query: queryWithContext, hasOrganizationContext } = useStoreGraphQLWithContext();\n const globalClient = useApolloClient();\n const [data, setData] = useState<unknown>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const getProductDetails = useCallback(\n async (input: StoreProductDetailsInput) => {\n setLoading(true);\n setError(null);\n try {\n const result = hasOrganizationContext\n ? ((await queryWithContext({\n query: StoreProductDetailsDocument,\n variables: { input },\n })) as { data?: StoreProductDetailsData })\n : await globalClient.query<StoreProductDetailsData>({\n query: StoreProductDetailsDocument,\n variables: { input },\n });\n const details = result.data?.storeProductDetails ?? null;\n setData(details);\n return details;\n } catch (err) {\n setError(err as Error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [globalClient, hasOrganizationContext, queryWithContext]\n );\n\n return {\n getProductDetails,\n data,\n loading,\n error,\n };\n}\n\n/**\n * Hook to fetch grouped products for homepage.\n */\nexport function useHomeGroupedProducts(options?: { skip?: boolean }) {\n const client = useStoreClient();\n const { defaultCompatibleWith } = useStore();\n const [data, setData] = useState<GroupedProducts | null>(null);\n const [loading, setLoading] = useState(!options?.skip);\n const [error, setError] = useState<Error | null>(null);\n\n const skip = options?.skip;\n\n const fetchData = useCallback(async () => {\n if (skip) {\n setLoading(false);\n return;\n }\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<{ homeGroupedProducts: GroupedProducts }>({\n query: HomeGroupedProductsDocument,\n variables: { compatibleWith: defaultCompatibleWith ?? null },\n fetchPolicy: 'cache-first',\n });\n setData(result.data?.homeGroupedProducts ?? null);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [client, defaultCompatibleWith, skip]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n data,\n featured: data?.featured ?? [],\n mostDownloaded: data?.mostDownloaded ?? [],\n recentlyAdded: data?.recentlyAdded ?? [],\n freeItems: data?.freeItems ?? [],\n loading,\n error,\n refetch: fetchData,\n };\n}\n\n/**\n * Hook to fetch featured products\n */\nexport function useFeaturedProducts(limit?: number) {\n const client = useStoreClient();\n const [products, setProducts] = useState<StoreProduct[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchData = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<{ featuredProducts: StoreProduct[] }>({\n query: FeaturedProductsDocument,\n variables: { limit },\n fetchPolicy: 'cache-first',\n });\n setProducts(result.data?.featuredProducts ?? []);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [client, limit]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n products,\n loading,\n error,\n refetch: fetchData,\n };\n}\n\n/**\n * Hook to fetch search suggestions for autocomplete\n */\nexport function useSearchSuggestions(\n query: string,\n options?: { limit?: number; types?: string[] }\n) {\n const client = useStoreClient();\n const [suggestions, setSuggestions] = useState<SearchSuggestion[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const shouldSkip = query.length < 2;\n\n const fetchData = useCallback(async () => {\n if (shouldSkip) {\n setSuggestions([]);\n return;\n }\n\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<{ searchSuggestions: SearchSuggestion[] }>({\n query: SearchSuggestionsDocument,\n variables: { query, limit: options?.limit, types: options?.types },\n fetchPolicy: 'network-only',\n });\n setSuggestions(result.data?.searchSuggestions ?? []);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [client, query, options?.limit, options?.types, shouldSkip]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n suggestions,\n loading,\n error,\n refetch: fetchData,\n };\n}\n\n/**\n * Lazy hook to fetch search suggestions on demand\n */\nexport function useLazySearchSuggestions() {\n const client = useStoreClient();\n const [suggestions, setSuggestions] = useState<SearchSuggestion[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const getSuggestions = useCallback(\n async (query: string, options?: { limit?: number; types?: string[] }) => {\n if (query.length < 2) {\n setSuggestions([]);\n return [];\n }\n\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<{ searchSuggestions: SearchSuggestion[] }>({\n query: SearchSuggestionsDocument,\n variables: { query, limit: options?.limit, types: options?.types },\n fetchPolicy: 'network-only',\n });\n const data = result.data?.searchSuggestions ?? [];\n setSuggestions(data);\n return data;\n } catch (err) {\n setError(err as Error);\n return [];\n } finally {\n setLoading(false);\n }\n },\n [client]\n );\n\n return {\n getSuggestions,\n suggestions,\n loading,\n error,\n };\n}\n\n/**\n * Hook to fetch trending search terms\n */\nexport function useTrendingSearches(options?: { limit?: number; type?: ProductType }) {\n const client = useStoreClient();\n const [terms, setTerms] = useState<string[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchData = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<{ trendingSearches: string[] }>({\n query: TrendingSearchesDocument,\n variables: { limit: options?.limit, type: options?.type },\n fetchPolicy: 'cache-first',\n });\n setTerms(result.data?.trendingSearches ?? []);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [client, options?.limit, options?.type]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n terms,\n loading,\n error,\n refetch: fetchData,\n };\n}\n\n/**\n * Hook to fetch filter options for dropdowns\n */\nexport function useFilterOptions(options?: { type?: ProductType; withProducts?: boolean }) {\n const client = useStoreClient();\n const [filterOptions, setFilterOptions] = useState<unknown>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchData = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<FilterOptionsData>({\n query: FilterOptionsDocument,\n variables: { type: options?.type, withProducts: options?.withProducts },\n fetchPolicy: 'cache-first',\n });\n setFilterOptions(result.data?.filterOptions ?? null);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [client, options?.type, options?.withProducts]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n filterOptions,\n loading,\n error,\n refetch: fetchData,\n };\n}\n\n// ============================================================================\n// Category Hooks\n// ============================================================================\n\n/**\n * Hook to fetch all categories\n */\nexport function useCategories() {\n const client = useStoreClient();\n const [categories, setCategories] = useState<ProductCategory[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchData = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<{ categories: ProductCategory[] }>({\n query: CategoriesDocument,\n fetchPolicy: 'cache-first',\n });\n setCategories(result.data?.categories ?? []);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [client]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n categories,\n loading,\n error,\n refetch: fetchData,\n };\n}\n\n// ============================================================================\n// Review Hooks\n// ============================================================================\n\n/**\n * Hook to fetch reviews for a product\n */\nexport function useProductReviews(productId: string, options?: { status?: string }) {\n const client = useStoreClient();\n const [reviews, setReviews] = useState<ProductReview[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchData = useCallback(async () => {\n if (!productId) {\n setLoading(false);\n return;\n }\n\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<{ productReviews: ProductReview[] }>({\n query: ProductReviewsDocument,\n variables: { productId, status: options?.status },\n fetchPolicy: 'cache-first',\n });\n setReviews(result.data?.productReviews ?? []);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [client, productId, options?.status]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n reviews,\n loading,\n error,\n refetch: fetchData,\n };\n}\n\n/**\n * Hook to fetch current user's review for a product\n */\nexport function useUserReviewForProduct(productId: string) {\n const client = useStoreClient();\n const [review, setReview] = useState<ProductReview | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchData = useCallback(async () => {\n if (!productId) {\n setLoading(false);\n return;\n }\n\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<{ userReviewForProduct: ProductReview | null }>({\n query: UserReviewForProductDocument,\n variables: { productId },\n fetchPolicy: 'network-only',\n });\n setReview(result.data?.userReviewForProduct ?? null);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [client, productId]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n review,\n loading,\n error,\n refetch: fetchData,\n };\n}\n\n/**\n * Hook to create a review\n */\nexport function useCreateReview() {\n const client = useStoreClient();\n const [review, setReview] = useState<ProductReview | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const createReview = useCallback(\n async (input: CreateReviewInput) => {\n setLoading(true);\n setError(null);\n try {\n const result = await client.mutate<{ createReview: ProductReview }>({\n mutation: CreateReviewDocument,\n variables: { input },\n });\n const data = result.data?.createReview ?? null;\n setReview(data);\n return data;\n } catch (err) {\n setError(err as Error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [client]\n );\n\n return {\n createReview,\n review,\n loading,\n error,\n };\n}\n\n/**\n * Hook to update a review\n */\nexport function useUpdateReview() {\n const client = useStoreClient();\n const [review, setReview] = useState<ProductReview | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const updateReview = useCallback(\n async (id: string, input: UpdateReviewInput) => {\n setLoading(true);\n setError(null);\n try {\n const result = await client.mutate<{ updateReview: ProductReview }>({\n mutation: UpdateReviewDocument,\n variables: { id, input },\n });\n const data = result.data?.updateReview ?? null;\n setReview(data);\n return data;\n } catch (err) {\n setError(err as Error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [client]\n );\n\n return {\n updateReview,\n review,\n loading,\n error,\n };\n}\n\n/**\n * Hook to delete a review\n */\nexport function useDeleteReview() {\n const client = useStoreClient();\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const deleteReview = useCallback(\n async (id: string) => {\n setLoading(true);\n setError(null);\n try {\n const result = await client.mutate<{ deleteReview: boolean }>({\n mutation: DeleteReviewDocument,\n variables: { id },\n });\n return result.data?.deleteReview ?? false;\n } catch (err) {\n setError(err as Error);\n return false;\n } finally {\n setLoading(false);\n }\n },\n [client]\n );\n\n return {\n deleteReview,\n loading,\n error,\n };\n}\n\n/**\n * Hook to mark review as helpful\n */\nexport function useMarkReviewHelpful() {\n const client = useStoreClient();\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const markHelpful = useCallback(\n async (id: string) => {\n setLoading(true);\n setError(null);\n try {\n const result = await client.mutate<{ markReviewHelpful: { id: string; helpful: number } }>({\n mutation: MarkReviewHelpfulDocument,\n variables: { id },\n });\n return result.data?.markReviewHelpful ?? null;\n } catch (err) {\n setError(err as Error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [client]\n );\n\n return {\n markHelpful,\n loading,\n error,\n };\n}\n\n// ============================================================================\n// Entitlement Hooks\n// ============================================================================\n\n/**\n * Hook to fetch current user's entitlements\n */\nexport function useMyEntitlements() {\n const { query: queryWithContext, hasOrganizationContext } = useStoreGraphQLWithContext();\n const globalClient = useApolloClient();\n const PAGE_SIZE = 20;\n const [allEntitlements, setAllEntitlements] = useState<unknown[]>([]);\n const [hasMore, setHasMore] = useState(false);\n const [currentOffset, setCurrentOffset] = useState(0);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchData = useCallback(\n async (fetchOffset = 0, append = false) => {\n setLoading(true);\n setError(null);\n try {\n const variables = { limit: PAGE_SIZE, offset: fetchOffset };\n const result = hasOrganizationContext\n ? ((await queryWithContext({\n query: MyEntitlementsDocument,\n variables,\n fetchPolicy: 'network-only',\n })) as { data?: { myEntitlements: unknown[] } })\n : await globalClient.query<{ myEntitlements: unknown[] }>({\n query: MyEntitlementsDocument,\n variables,\n fetchPolicy: 'network-only',\n });\n const fetched = result.data?.myEntitlements ?? [];\n if (append) {\n setAllEntitlements((prev) => [...prev, ...fetched]);\n } else {\n setAllEntitlements(fetched);\n }\n setHasMore(fetched.length === PAGE_SIZE);\n setCurrentOffset(fetchOffset);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n },\n [globalClient, hasOrganizationContext, queryWithContext]\n );\n\n useEffect(() => {\n fetchData(0);\n }, [fetchData]);\n\n const loadMore = useCallback(() => {\n if (!hasMore || loading) return;\n fetchData(currentOffset + PAGE_SIZE, true);\n }, [fetchData, hasMore, loading, currentOffset]);\n\n return {\n entitlements: allEntitlements,\n hasMore,\n loading,\n error,\n refetch: () => fetchData(0),\n loadMore,\n };\n}\n\n/**\n * Hook to check entitlement for a product\n */\nexport function useCheckEntitlement(productId: string) {\n const client = useStoreClient();\n const [entitlement, setEntitlement] = useState<unknown>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchData = useCallback(async () => {\n if (!productId) {\n setLoading(false);\n return;\n }\n\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<CheckEntitlementData>({\n query: CheckEntitlementDocument,\n variables: { productId },\n fetchPolicy: 'network-only',\n });\n setEntitlement(result.data?.checkEntitlement ?? null);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [client, productId]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n entitlement,\n loading,\n error,\n refetch: fetchData,\n };\n}\n\n// ============================================================================\n// Order Hooks\n// ============================================================================\n\n/**\n * Hook to fetch workspace store orders\n */\nexport function useWorkspaceStoreOrders(\n billingAccountId: string,\n page: number,\n limit: number,\n options?: { status?: string; search?: string }\n) {\n const client = useStoreClient();\n const [orders, setOrders] = useState<unknown[]>([]);\n const [total, setTotal] = useState(0);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchData = useCallback(async () => {\n if (!billingAccountId) {\n setLoading(false);\n return;\n }\n\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<{\n workspaceStoreOrders: { total: number; orders: unknown[] };\n }>({\n query: WorkspaceStoreOrdersDocument,\n variables: {\n billingAccountId,\n page,\n limit,\n status: options?.status,\n search: options?.search,\n },\n fetchPolicy: 'network-only',\n });\n setOrders(result.data?.workspaceStoreOrders?.orders ?? []);\n setTotal(result.data?.workspaceStoreOrders?.total ?? 0);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [client, billingAccountId, page, limit, options?.status, options?.search]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n orders,\n total,\n loading,\n error,\n refetch: fetchData,\n };\n}\n\n// ============================================================================\n// Publisher Hooks\n// ============================================================================\n\n/**\n * Hook to fetch publisher's products\n */\nexport function useMyPublishedProducts() {\n const client = useStoreClient();\n const [allProducts, setAllProducts] = useState<StoreProduct[]>([]);\n const [hasMore, setHasMore] = useState(false);\n const [currentOffset, setCurrentOffset] = useState(0);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const PAGE_SIZE = 20;\n\n const fetchData = useCallback(\n async (fetchOffset = 0, append = false) => {\n setLoading(true);\n setError(null);\n try {\n const result = await client.query<{ publishedProducts: StoreProduct[] }>({\n query: MyPublishedProductsDocument,\n variables: { limit: PAGE_SIZE, offset: fetchOffset },\n fetchPolicy: 'network-only',\n });\n const fetched = result.data?.publishedProducts ?? [];\n if (append) {\n setAllProducts((prev) => [...prev, ...fetched]);\n } else {\n setAllProducts(fetched);\n }\n setHasMore(fetched.length === PAGE_SIZE);\n setCurrentOffset(fetchOffset + fetched.length);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n },\n [client]\n );\n\n const loadMore = useCallback(() => {\n if (!hasMore || loading) return;\n void fetchData(currentOffset, true);\n }, [fetchData, hasMore, loading, currentOffset]);\n\n useEffect(() => {\n void fetchData(0, false);\n }, [fetchData]);\n\n return {\n products: allProducts,\n hasMore,\n loading,\n error,\n refetch: () => fetchData(0, false),\n loadMore,\n };\n}\n\n/**\n * Hook to fetch developer earnings\n */\nexport function useDeveloperEarnings(options?: {\n period?: string;\n startDate?: string;\n endDate?: string;\n}) {\n const { query: queryWithContext, hasOrganizationContext } = useStoreGraphQLWithContext();\n const globalClient = useApolloClient();\n const [earnings, setEarnings] = useState<unknown>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchData = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const result = hasOrganizationContext\n ? ((await queryWithContext({\n query: DeveloperEarningsDocument,\n variables: { input: options },\n fetchPolicy: 'network-only',\n })) as { data?: DeveloperEarningsData })\n : await globalClient.query<DeveloperEarningsData>({\n query: DeveloperEarningsDocument,\n variables: { input: options },\n fetchPolicy: 'network-only',\n });\n setEarnings(result.data?.developerEarnings ?? null);\n } catch (err) {\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n }, [globalClient, hasOrganizationContext, options, queryWithContext]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n return {\n earnings,\n loading,\n error,\n refetch: fetchData,\n };\n}\n\n// ============================================================================\n// Re-export types for convenience\n// ============================================================================\n\nexport type {\n BrowseStoreInput,\n StoreProductDetailsInput,\n ProductType,\n CreateReviewInput,\n UpdateReviewInput,\n StoreProduct,\n ProductReview,\n ProductCategory,\n SearchSuggestion,\n GroupedProducts,\n BrowseStoreResult,\n};\n"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -8,6 +8,6 @@ import { StoreRoot as mt } from "./StoreRoot.js";
8
8
  import { StoreAdminRoot as ht } from "./StoreAdminRoot.js";
9
9
  import { useProductSearch as gt } from "./hooks/useProductSearch.js";
10
10
  import { calculateCartTotals as _t, debounce as vt, formatFileSize as yt, formatNumber as bt, formatPrice as xt, formatPriceForModel as St, generateCartItemId as Ct, getDaysUntilExpiry as wt, getItemTypeName as Tt, getPricingModelName as Et, getRatingStars as Dt, getStatusColor as Ot, isLicenseExpiringSoon as kt, maskLicenseKey as At, truncate as jt, validateLicenseKey as Mt } from "./utils/index.js";
11
- import { useBrowseStore as Nt, useBrowseStoreWithContext as Pt, useCategories as Ft, useCheckEntitlement as It, useCreateReview as Lt, useDeleteReview as Rt, useDeveloperEarnings as zt, useFeaturedProducts as Bt, useFilterOptions as Vt, useHomeGroupedProducts as Ht, useLazyBrowseStore as Ut, useLazySearchSuggestions as Wt, useLazyStoreProductDetails as Gt, useMarkReviewHelpful as Kt, useMyEntitlements as qt, useMyPublishedProducts as Jt, useProductReviews as Yt, useSearchSuggestions as Xt, useStoreProductDetails as Zt, useTrendingSearches as Qt, useUpdateReview as $t, useUserReviewForProduct as en, useWorkspaceStoreOrders as tn } from "./hooks/useStoreGraphQL.js";
12
- import { enTranslations as nn } from "./translations/en.js";
13
- export { i as AddToCartDocument, a as BrowseStoreDocument, o as CategoriesDocument, s as CheckEntitlementDocument, c as CheckoutDocument, l as ClearCartDocument, u as CreateProductForPublisherDocument, d as CreateReviewDocument, f as CreateStoreOrderDocument, p as DeleteReviewDocument, m as DeveloperEarningsDocument, h as FeaturedProductsDocument, g as FilterOptionsDocument, _ as GetCartDocument, v as GetMyOrdersDocument, y as GetMyStoreInstallationsDocument, b as GetProductDocument, x as GetProductsDocument, S as GetStoreAppInstallationDocument, C as HomeGroupedProductsDocument, w as InstallationStatusUpdatedDocument, T as LicenseStatusUpdatedDocument, E as MarkReviewHelpfulDocument, D as MyEntitlementsDocument, O as MyPublishedProductsDocument, k as OrderStatusUpdatedDocument, A as ProductReviewsDocument, j as RecordAppUninstallationDocument, M as RemoveFromCartDocument, t as STORE_PERMISSIONS, N as SearchSuggestionsDocument, ht as StoreAdminRoot, P as StoreProductDetailsDocument, mt as StoreRoot, F as SubmissionStatusUpdatedDocument, I as TrendingSearchesDocument, L as UpdateCartItemDocument, R as UpdateReviewDocument, z as UserReviewForProductDocument, B as WorkspaceStoreOrdersDocument, _t as calculateCartTotals, vt as debounce, yt as formatFileSize, bt as formatNumber, xt as formatPrice, St as formatPriceForModel, Ct as generateCartItemId, wt as getDaysUntilExpiry, Tt as getItemTypeName, Et as getPricingModelName, Dt as getRatingStars, Ot as getStatusColor, kt as isLicenseExpiringSoon, At as maskLicenseKey, nn as storeTranslations, jt as truncate, V as useAddToCartMutation, ft as useBackendCart, Nt as useBrowseStore, H as useBrowseStoreLazyQuery, U as useBrowseStoreQuery, W as useBrowseStoreSuspenseQuery, Pt as useBrowseStoreWithContext, pt as useCart, Ft as useCategories, G as useCategoriesLazyQuery, K as useCategoriesQuery, q as useCategoriesSuspenseQuery, It as useCheckEntitlement, J as useCheckEntitlementLazyQuery, Y as useCheckEntitlementQuery, X as useCheckEntitlementSuspenseQuery, Z as useCheckoutMutation, Q as useClearCartMutation, $ as useCreateProductForPublisherMutation, Lt as useCreateReview, ee as useCreateReviewMutation, te as useCreateStoreOrderMutation, Rt as useDeleteReview, ne as useDeleteReviewMutation, zt as useDeveloperEarnings, re as useDeveloperEarningsLazyQuery, ie as useDeveloperEarningsQuery, ae as useDeveloperEarningsSuspenseQuery, Bt as useFeaturedProducts, oe as useFeaturedProductsLazyQuery, se as useFeaturedProductsQuery, ce as useFeaturedProductsSuspenseQuery, Vt as useFilterOptions, le as useFilterOptionsLazyQuery, ue as useFilterOptionsQuery, de as useFilterOptionsSuspenseQuery, fe as useGetCartLazyQuery, pe as useGetCartQuery, me as useGetCartSuspenseQuery, he as useGetMyOrdersLazyQuery, ge as useGetMyOrdersQuery, _e as useGetMyOrdersSuspenseQuery, ve as useGetMyStoreInstallationsLazyQuery, ye as useGetMyStoreInstallationsQuery, be as useGetMyStoreInstallationsSuspenseQuery, xe as useGetProductLazyQuery, Se as useGetProductQuery, Ce as useGetProductSuspenseQuery, we as useGetProductsLazyQuery, Te as useGetProductsQuery, Ee as useGetProductsSuspenseQuery, De as useGetStoreAppInstallationLazyQuery, Oe as useGetStoreAppInstallationQuery, ke as useGetStoreAppInstallationSuspenseQuery, Ht as useHomeGroupedProducts, Ae as useHomeGroupedProductsLazyQuery, je as useHomeGroupedProductsQuery, Me as useHomeGroupedProductsSuspenseQuery, Ne as useInstallationStatusUpdatedSubscription, Ut as useLazyBrowseStore, Wt as useLazySearchSuggestions, Gt as useLazyStoreProductDetails, Pe as useLicenseStatusUpdatedSubscription, Kt as useMarkReviewHelpful, Fe as useMarkReviewHelpfulMutation, qt as useMyEntitlements, Ie as useMyEntitlementsLazyQuery, Le as useMyEntitlementsQuery, Re as useMyEntitlementsSuspenseQuery, Jt as useMyPublishedProducts, ze as useMyPublishedProductsLazyQuery, Be as useMyPublishedProductsQuery, Ve as useMyPublishedProductsSuspenseQuery, He as useOrderStatusUpdatedSubscription, Yt as useProductReviews, Ue as useProductReviewsLazyQuery, We as useProductReviewsQuery, Ge as useProductReviewsSuspenseQuery, gt as useProductSearch, Ke as useRecordAppUninstallationMutation, qe as useRemoveFromCartMutation, Xt as useSearchSuggestions, Je as useSearchSuggestionsLazyQuery, Ye as useSearchSuggestionsQuery, Xe as useSearchSuggestionsSuspenseQuery, e as useStore, n as useStorePermissions, Zt as useStoreProductDetails, Ze as useStoreProductDetailsLazyQuery, Qe as useStoreProductDetailsQuery, $e as useStoreProductDetailsSuspenseQuery, r as useStoreStore, et as useSubmissionStatusUpdatedSubscription, Qt as useTrendingSearches, tt as useTrendingSearchesLazyQuery, nt as useTrendingSearchesQuery, rt as useTrendingSearchesSuspenseQuery, it as useUpdateCartItemMutation, $t as useUpdateReview, at as useUpdateReviewMutation, en as useUserReviewForProduct, ot as useUserReviewForProductLazyQuery, st as useUserReviewForProductQuery, ct as useUserReviewForProductSuspenseQuery, tn as useWorkspaceStoreOrders, lt as useWorkspaceStoreOrdersLazyQuery, ut as useWorkspaceStoreOrdersQuery, dt as useWorkspaceStoreOrdersSuspenseQuery, Mt as validateLicenseKey };
11
+ import { useBrowseStore as Nt, useBrowseStoreWithContext as Pt, useCategories as Ft, useCheckEntitlement as It, useCreateReview as Lt, useDeleteReview as Rt, useFeaturedProducts as zt, useFilterOptions as Bt, useHomeGroupedProducts as Vt, useLazyBrowseStore as Ht, useLazySearchSuggestions as Ut, useLazyStoreProductDetails as Wt, useMarkReviewHelpful as Gt, useMyEntitlements as Kt, useProductReviews as qt, useSearchSuggestions as Jt, useStoreProductDetails as Yt, useTrendingSearches as Xt, useUpdateReview as Zt, useUserReviewForProduct as Qt, useWorkspaceStoreOrders as $t } from "./hooks/useStoreGraphQL.js";
12
+ import { enTranslations as en } from "./translations/en.js";
13
+ export { i as AddToCartDocument, a as BrowseStoreDocument, o as CategoriesDocument, s as CheckEntitlementDocument, c as CheckoutDocument, l as ClearCartDocument, u as CreateProductForPublisherDocument, d as CreateReviewDocument, f as CreateStoreOrderDocument, p as DeleteReviewDocument, m as DeveloperEarningsDocument, h as FeaturedProductsDocument, g as FilterOptionsDocument, _ as GetCartDocument, v as GetMyOrdersDocument, y as GetMyStoreInstallationsDocument, b as GetProductDocument, x as GetProductsDocument, S as GetStoreAppInstallationDocument, C as HomeGroupedProductsDocument, w as InstallationStatusUpdatedDocument, T as LicenseStatusUpdatedDocument, E as MarkReviewHelpfulDocument, D as MyEntitlementsDocument, O as MyPublishedProductsDocument, k as OrderStatusUpdatedDocument, A as ProductReviewsDocument, j as RecordAppUninstallationDocument, M as RemoveFromCartDocument, t as STORE_PERMISSIONS, N as SearchSuggestionsDocument, ht as StoreAdminRoot, P as StoreProductDetailsDocument, mt as StoreRoot, F as SubmissionStatusUpdatedDocument, I as TrendingSearchesDocument, L as UpdateCartItemDocument, R as UpdateReviewDocument, z as UserReviewForProductDocument, B as WorkspaceStoreOrdersDocument, _t as calculateCartTotals, vt as debounce, yt as formatFileSize, bt as formatNumber, xt as formatPrice, St as formatPriceForModel, Ct as generateCartItemId, wt as getDaysUntilExpiry, Tt as getItemTypeName, Et as getPricingModelName, Dt as getRatingStars, Ot as getStatusColor, kt as isLicenseExpiringSoon, At as maskLicenseKey, en as storeTranslations, jt as truncate, V as useAddToCartMutation, ft as useBackendCart, Nt as useBrowseStore, H as useBrowseStoreLazyQuery, U as useBrowseStoreQuery, W as useBrowseStoreSuspenseQuery, Pt as useBrowseStoreWithContext, pt as useCart, Ft as useCategories, G as useCategoriesLazyQuery, K as useCategoriesQuery, q as useCategoriesSuspenseQuery, It as useCheckEntitlement, J as useCheckEntitlementLazyQuery, Y as useCheckEntitlementQuery, X as useCheckEntitlementSuspenseQuery, Z as useCheckoutMutation, Q as useClearCartMutation, $ as useCreateProductForPublisherMutation, Lt as useCreateReview, ee as useCreateReviewMutation, te as useCreateStoreOrderMutation, Rt as useDeleteReview, ne as useDeleteReviewMutation, re as useDeveloperEarningsLazyQuery, ie as useDeveloperEarningsQuery, ae as useDeveloperEarningsSuspenseQuery, zt as useFeaturedProducts, oe as useFeaturedProductsLazyQuery, se as useFeaturedProductsQuery, ce as useFeaturedProductsSuspenseQuery, Bt as useFilterOptions, le as useFilterOptionsLazyQuery, ue as useFilterOptionsQuery, de as useFilterOptionsSuspenseQuery, fe as useGetCartLazyQuery, pe as useGetCartQuery, me as useGetCartSuspenseQuery, he as useGetMyOrdersLazyQuery, ge as useGetMyOrdersQuery, _e as useGetMyOrdersSuspenseQuery, ve as useGetMyStoreInstallationsLazyQuery, ye as useGetMyStoreInstallationsQuery, be as useGetMyStoreInstallationsSuspenseQuery, xe as useGetProductLazyQuery, Se as useGetProductQuery, Ce as useGetProductSuspenseQuery, we as useGetProductsLazyQuery, Te as useGetProductsQuery, Ee as useGetProductsSuspenseQuery, De as useGetStoreAppInstallationLazyQuery, Oe as useGetStoreAppInstallationQuery, ke as useGetStoreAppInstallationSuspenseQuery, Vt as useHomeGroupedProducts, Ae as useHomeGroupedProductsLazyQuery, je as useHomeGroupedProductsQuery, Me as useHomeGroupedProductsSuspenseQuery, Ne as useInstallationStatusUpdatedSubscription, Ht as useLazyBrowseStore, Ut as useLazySearchSuggestions, Wt as useLazyStoreProductDetails, Pe as useLicenseStatusUpdatedSubscription, Gt as useMarkReviewHelpful, Fe as useMarkReviewHelpfulMutation, Kt as useMyEntitlements, Ie as useMyEntitlementsLazyQuery, Le as useMyEntitlementsQuery, Re as useMyEntitlementsSuspenseQuery, ze as useMyPublishedProductsLazyQuery, Be as useMyPublishedProductsQuery, Ve as useMyPublishedProductsSuspenseQuery, He as useOrderStatusUpdatedSubscription, qt as useProductReviews, Ue as useProductReviewsLazyQuery, We as useProductReviewsQuery, Ge as useProductReviewsSuspenseQuery, gt as useProductSearch, Ke as useRecordAppUninstallationMutation, qe as useRemoveFromCartMutation, Jt as useSearchSuggestions, Je as useSearchSuggestionsLazyQuery, Ye as useSearchSuggestionsQuery, Xe as useSearchSuggestionsSuspenseQuery, e as useStore, n as useStorePermissions, Yt as useStoreProductDetails, Ze as useStoreProductDetailsLazyQuery, Qe as useStoreProductDetailsQuery, $e as useStoreProductDetailsSuspenseQuery, r as useStoreStore, et as useSubmissionStatusUpdatedSubscription, Xt as useTrendingSearches, tt as useTrendingSearchesLazyQuery, nt as useTrendingSearchesQuery, rt as useTrendingSearchesSuspenseQuery, it as useUpdateCartItemMutation, Zt as useUpdateReview, at as useUpdateReviewMutation, Qt as useUserReviewForProduct, ot as useUserReviewForProductLazyQuery, st as useUserReviewForProductQuery, ct as useUserReviewForProductSuspenseQuery, $t as useWorkspaceStoreOrders, lt as useWorkspaceStoreOrdersLazyQuery, ut as useWorkspaceStoreOrdersQuery, dt as useWorkspaceStoreOrdersSuspenseQuery, Mt as validateLicenseKey };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-store",
3
- "version": "2026.626.1",
3
+ "version": "2026.626.2",
4
4
  "description": "Store microfrontend for Burdenoff products",
5
5
  "type": "module",
6
6
  "files": [
@@ -1,92 +0,0 @@
1
- import { useProductReviews as e } from "../hooks/useStoreGraphQL.js";
2
- import { useI18n as t } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
3
- import { ArrowLeft as n, Star as r } from "lucide-react";
4
- import { jsx as i, jsxs as a } from "react/jsx-runtime";
5
- import { useNavigate as o, useParams as s } from "react-router-dom";
6
- import { IllustratedEmptyState as c, PagePurpose as l } from "@burdenoff/fe-libs/ui";
7
- //#region src/pages/ProductReviewsPage.tsx
8
- var u = () => {
9
- let u = o(), { productId: d } = s(), { reviews: f, loading: p, error: m } = e(d ?? ""), { t: h } = t();
10
- return /* @__PURE__ */ a("div", {
11
- className: "flex h-full flex-col",
12
- children: [/* @__PURE__ */ i("header", {
13
- className: "border-b border-border-seam bg-bg-surface px-6 py-4",
14
- children: /* @__PURE__ */ a("div", {
15
- className: "mx-auto flex max-w-4xl items-center gap-3",
16
- children: [/* @__PURE__ */ i("button", {
17
- type: "button",
18
- onClick: () => u(-1),
19
- "aria-label": "Go back",
20
- className: "cursor-pointer rounded-lg p-2 text-text-muted hover:bg-bg-sunken hover:text-text-primary",
21
- children: /* @__PURE__ */ i(n, { className: "size-5" })
22
- }), /* @__PURE__ */ a("div", { children: [/* @__PURE__ */ i("h1", {
23
- className: "text-2xl font-bold text-text-primary",
24
- children: h("pages.productReviews.title", { defaultValue: "Product Reviews" })
25
- }), /* @__PURE__ */ i("p", {
26
- className: "text-sm text-text-muted",
27
- children: h("pages.productReviews.subtitle", { defaultValue: "Moderate and inspect product feedback" })
28
- })] })]
29
- })
30
- }), /* @__PURE__ */ i("main", {
31
- className: "flex-1 overflow-y-auto p-6",
32
- children: /* @__PURE__ */ a("div", {
33
- className: "mx-auto max-w-4xl",
34
- children: [/* @__PURE__ */ i(l, {
35
- className: "mb-4",
36
- children: "Read what customers think of this product in their own words. Use these ratings and comments to gauge quality before installing, spot recurring issues, and — as a moderator — keep an eye on feedback that may need a response or review."
37
- }), p ? /* @__PURE__ */ i("p", {
38
- role: "status",
39
- className: "text-sm text-text-muted",
40
- children: "Loading reviews…"
41
- }) : m ? /* @__PURE__ */ i("p", {
42
- role: "alert",
43
- className: "text-sm text-status-error-text",
44
- children: m.message
45
- }) : f.length === 0 ? /* @__PURE__ */ i(c, {
46
- illustration: "empty-notifications",
47
- title: "No reviews yet",
48
- description: "This product hasn't received any reviews. Once customers leave feedback, it will appear here for you to read and moderate."
49
- }) : /* @__PURE__ */ i("ul", {
50
- className: "space-y-3",
51
- children: f.map((e) => /* @__PURE__ */ a("li", {
52
- className: "rounded-xl border border-border-seam bg-bg-surface p-4 transition-[box-shadow,border-color] hover:border-border-strong hover:shadow-[var(--shadow-pop)]",
53
- children: [
54
- /* @__PURE__ */ a("div", {
55
- className: "flex items-center justify-between",
56
- children: [/* @__PURE__ */ i("p", {
57
- className: "font-medium text-text-primary",
58
- children: e.title || h("pages.productReviews.untitled", { defaultValue: "Untitled review" })
59
- }), /* @__PURE__ */ a("span", {
60
- className: "inline-flex items-center gap-1 text-sm text-text-muted",
61
- children: [
62
- /* @__PURE__ */ i(r, { className: "size-4" }),
63
- " ",
64
- e.rating,
65
- "/5"
66
- ]
67
- })]
68
- }),
69
- /* @__PURE__ */ i("p", {
70
- className: "mt-2 text-sm text-text-muted",
71
- children: e.comment || h("pages.productReviews.noComment", { defaultValue: "No comment provided." })
72
- }),
73
- /* @__PURE__ */ a("p", {
74
- className: "mt-2 text-xs text-text-muted",
75
- children: [
76
- "Status: ",
77
- e.status,
78
- " • Helpful: ",
79
- e.helpful
80
- ]
81
- })
82
- ]
83
- }, e.id))
84
- })]
85
- })
86
- })]
87
- });
88
- };
89
- //#endregion
90
- export { u as ProductReviewsPage };
91
-
92
- //# sourceMappingURL=ProductReviewsPage.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ProductReviewsPage.js","names":[],"sources":["../../src/pages/ProductReviewsPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useNavigate, useParams } from 'react-router-dom';\nimport { ArrowLeft, Star } from 'lucide-react';\nimport { useProductReviews } from '../hooks/useStoreGraphQL';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { PagePurpose, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\n\nexport const ProductReviewsPage: FC = () => {\n const navigate = useNavigate();\n const { productId } = useParams<{ productId: string }>();\n const { reviews, loading, error } = useProductReviews(productId ?? '');\n const { t } = useI18n();\n\n return (\n <div className=\"flex h-full flex-col\">\n <header className=\"border-b border-border-seam bg-bg-surface px-6 py-4\">\n <div className=\"mx-auto flex max-w-4xl items-center gap-3\">\n <button\n type=\"button\"\n onClick={() => navigate(-1)}\n aria-label=\"Go back\"\n className=\"cursor-pointer rounded-lg p-2 text-text-muted hover:bg-bg-sunken hover:text-text-primary\"\n >\n <ArrowLeft className=\"size-5\" />\n </button>\n <div>\n <h1 className=\"text-2xl font-bold text-text-primary\">\n {t('pages.productReviews.title', { defaultValue: 'Product Reviews' })}\n </h1>\n <p className=\"text-sm text-text-muted\">\n {t('pages.productReviews.subtitle', {\n defaultValue: 'Moderate and inspect product feedback',\n })}\n </p>\n </div>\n </div>\n </header>\n\n <main className=\"flex-1 overflow-y-auto p-6\">\n <div className=\"mx-auto max-w-4xl\">\n <PagePurpose className=\"mb-4\">\n Read what customers think of this product in their own words. Use these ratings and\n comments to gauge quality before installing, spot recurring issues, and — as a\n moderator — keep an eye on feedback that may need a response or review.\n </PagePurpose>\n {loading ? (\n <p role=\"status\" className=\"text-sm text-text-muted\">\n Loading reviews…\n </p>\n ) : error ? (\n <p role=\"alert\" className=\"text-sm text-status-error-text\">\n {error.message}\n </p>\n ) : reviews.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-notifications\"\n title=\"No reviews yet\"\n description=\"This product hasn't received any reviews. Once customers leave feedback, it will appear here for you to read and moderate.\"\n />\n ) : (\n <ul className=\"space-y-3\">\n {reviews.map((review) => (\n <li\n key={review.id}\n className=\"rounded-xl border border-border-seam bg-bg-surface p-4 transition-[box-shadow,border-color] hover:border-border-strong hover:shadow-[var(--shadow-pop)]\"\n >\n <div className=\"flex items-center justify-between\">\n <p className=\"font-medium text-text-primary\">\n {review.title ||\n t('pages.productReviews.untitled', { defaultValue: 'Untitled review' })}\n </p>\n <span className=\"inline-flex items-center gap-1 text-sm text-text-muted\">\n <Star className=\"size-4\" /> {review.rating}/5\n </span>\n </div>\n <p className=\"mt-2 text-sm text-text-muted\">\n {review.comment ||\n t('pages.productReviews.noComment', { defaultValue: 'No comment provided.' })}\n </p>\n <p className=\"mt-2 text-xs text-text-muted\">\n Status: {review.status} • Helpful: {review.helpful}\n </p>\n </li>\n ))}\n </ul>\n )}\n </div>\n </main>\n </div>\n );\n};\n"],"mappings":";;;;;;;AAOA,IAAa,UAA+B;CAC1C,IAAM,IAAW,GAAa,EACxB,EAAE,iBAAc,GAAkC,EAClD,EAAE,YAAS,YAAS,aAAU,EAAkB,KAAa,GAAG,EAChE,EAAE,SAAM,GAAS;AAEvB,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,UAAD;GAAQ,WAAU;aAChB,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,UAAD;KACE,MAAK;KACL,eAAe,EAAS,GAAG;KAC3B,cAAW;KACX,WAAU;eAEV,kBAAC,GAAD,EAAW,WAAU,UAAW,CAAA;KACzB,CAAA,EACT,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;KAAI,WAAU;eACX,EAAE,8BAA8B,EAAE,cAAc,mBAAmB,CAAC;KAClE,CAAA,EACL,kBAAC,KAAD;KAAG,WAAU;eACV,EAAE,iCAAiC,EAClC,cAAc,yCACf,CAAC;KACA,CAAA,CACA,EAAA,CAAA,CACF;;GACC,CAAA,EAET,kBAAC,QAAD;GAAM,WAAU;aACd,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KAAa,WAAU;eAAO;KAIhB,CAAA,EACb,IACC,kBAAC,KAAD;KAAG,MAAK;KAAS,WAAU;eAA0B;KAEjD,CAAA,GACF,IACF,kBAAC,KAAD;KAAG,MAAK;KAAQ,WAAU;eACvB,EAAM;KACL,CAAA,GACF,EAAQ,WAAW,IACrB,kBAAC,GAAD;KACE,cAAa;KACb,OAAM;KACN,aAAY;KACZ,CAAA,GAEF,kBAAC,MAAD;KAAI,WAAU;eACX,EAAQ,KAAK,MACZ,kBAAC,MAAD;MAEE,WAAU;gBAFZ;OAIE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAO,SACN,EAAE,iCAAiC,EAAE,cAAc,mBAAmB,CAAC;SACvE,CAAA,EACJ,kBAAC,QAAD;SAAM,WAAU;mBAAhB;UACE,kBAAC,GAAD,EAAM,WAAU,UAAW,CAAA;;UAAE,EAAO;UAAO;UACtC;WACH;;OACN,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAO,WACN,EAAE,kCAAkC,EAAE,cAAc,wBAAwB,CAAC;QAC7E,CAAA;OACJ,kBAAC,KAAD;QAAG,WAAU;kBAAb;SAA4C;SACjC,EAAO;SAAO;SAAa,EAAO;SACzC;;OACD;QAnBE,EAAO,GAmBT,CACL;KACC,CAAA,CAEH;;GACD,CAAA,CACH"}
@@ -1,195 +0,0 @@
1
- import { useStore as e } from "../providers/StoreProvider.js";
2
- import { useMyPublishedProducts as t } from "../hooks/useStoreGraphQL.js";
3
- import { useMemo as n } from "react";
4
- import { useI18n as r } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
5
- import { ArrowLeft as i, Download as a, LineChart as o, MessageSquare as s, Plus as c, Star as l } from "lucide-react";
6
- import { jsx as u, jsxs as d } from "react/jsx-runtime";
7
- import { useNavigate as f } from "react-router-dom";
8
- import { EmphasisPanel as p, GlassCard as m, IllustratedEmptyState as h, NextSteps as g, PagePurpose as _ } from "@burdenoff/fe-libs/ui";
9
- //#region src/pages/PublisherDashboardPage.tsx
10
- var v = () => {
11
- let v = f(), { basePath: y } = e(), { t: b } = r(), { products: x, loading: S, error: C, refetch: w } = t(), T = n(() => {
12
- let e = x.length;
13
- return {
14
- totalProducts: e,
15
- totalDownloads: x.reduce((e, t) => e + (t.downloads ?? 0), 0),
16
- avgRating: e > 0 ? x.reduce((e, t) => e + (t.rating ?? 0), 0) / e : 0
17
- };
18
- }, [x]);
19
- return /* @__PURE__ */ d("div", {
20
- className: "flex h-full flex-col",
21
- children: [/* @__PURE__ */ u("header", {
22
- className: "border-b border-border-seam bg-bg-surface px-6 py-4",
23
- children: /* @__PURE__ */ d("div", {
24
- className: "mx-auto flex max-w-6xl items-center justify-between",
25
- children: [/* @__PURE__ */ d("div", {
26
- className: "flex items-center gap-3",
27
- children: [/* @__PURE__ */ u("button", {
28
- type: "button",
29
- onClick: () => v(-1),
30
- "aria-label": "Go back",
31
- className: "cursor-pointer rounded-lg p-2 text-text-muted transition-colors hover:bg-bg-sunken hover:text-text-primary",
32
- children: /* @__PURE__ */ u(i, { className: "size-5" })
33
- }), /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("h1", {
34
- className: "text-2xl font-bold text-text-primary",
35
- children: b("pages.publisherDashboard.title", { defaultValue: "Publisher Dashboard" })
36
- }), /* @__PURE__ */ u("p", {
37
- className: "text-sm text-text-muted",
38
- children: b("pages.publisherDashboard.subtitle", { defaultValue: "Manage your published products and performance" })
39
- })] })]
40
- }), /* @__PURE__ */ d("button", {
41
- type: "button",
42
- onClick: () => v(`${y}/publisher/submit`),
43
- className: "inline-flex cursor-pointer items-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-semibold text-action-primary-text",
44
- children: [/* @__PURE__ */ u(c, { className: "size-4" }), "Submit Product"]
45
- })]
46
- })
47
- }), /* @__PURE__ */ u("main", {
48
- className: "flex-1 overflow-y-auto p-6",
49
- children: /* @__PURE__ */ d("div", {
50
- className: "mx-auto max-w-6xl space-y-6",
51
- children: [
52
- /* @__PURE__ */ u(_, { children: "Your home base as a marketplace seller. Track how your published products are performing — downloads, ratings and revenue — submit new products for review, and respond to customer reviews. Use it to decide what to build next and to keep your listings healthy." }),
53
- /* @__PURE__ */ u(g, {
54
- storageKey: "store-publisher-dashboard",
55
- steps: [
56
- {
57
- id: "submit",
58
- label: "Submit a product",
59
- description: "List a new app or tool for review and publishing.",
60
- icon: /* @__PURE__ */ u(c, { className: "size-4" }),
61
- onClick: () => v(`${y}/publisher/submit`),
62
- done: T.totalProducts > 0
63
- },
64
- {
65
- id: "revenue",
66
- label: "Check your earnings",
67
- description: "See revenue and payouts across your products.",
68
- icon: /* @__PURE__ */ u(o, { className: "size-4" }),
69
- onClick: () => v(`${y}/publisher/revenue`)
70
- },
71
- {
72
- id: "track",
73
- label: "Track submission status",
74
- description: "Follow products through the review pipeline.",
75
- onClick: () => v(`${y}/publisher/submissions`)
76
- }
77
- ]
78
- }),
79
- /* @__PURE__ */ d("div", {
80
- className: "grid gap-4 sm:grid-cols-3",
81
- children: [
82
- /* @__PURE__ */ d(m, {
83
- treatment: "metric",
84
- className: "p-4",
85
- children: [/* @__PURE__ */ u("p", {
86
- className: "text-xs uppercase tracking-wide text-text-muted",
87
- children: b("pages.publisherDashboard.totalProducts", { defaultValue: "Published products" })
88
- }), /* @__PURE__ */ u("p", {
89
- className: "mt-2 text-2xl font-bold tabular-nums text-text-primary",
90
- children: T.totalProducts
91
- })]
92
- }),
93
- /* @__PURE__ */ d(m, {
94
- treatment: "metric",
95
- className: "p-4",
96
- children: [/* @__PURE__ */ u("p", {
97
- className: "text-xs uppercase tracking-wide text-text-muted",
98
- children: b("pages.publisherDashboard.totalInstalls", { defaultValue: "Total downloads" })
99
- }), /* @__PURE__ */ u("p", {
100
- className: "mt-2 text-2xl font-bold tabular-nums text-text-primary",
101
- children: T.totalDownloads
102
- })]
103
- }),
104
- /* @__PURE__ */ d(m, {
105
- treatment: "metric",
106
- className: "p-4",
107
- children: [/* @__PURE__ */ u("p", {
108
- className: "text-xs uppercase tracking-wide text-text-muted",
109
- children: b("pages.publisherDashboard.avgRating", { defaultValue: "Average rating" })
110
- }), /* @__PURE__ */ u("p", {
111
- className: "mt-2 text-2xl font-bold tabular-nums text-text-primary",
112
- children: T.avgRating.toFixed(1)
113
- })]
114
- })
115
- ]
116
- }),
117
- /* @__PURE__ */ d(p, { children: [/* @__PURE__ */ d("div", {
118
- className: "mb-4 flex items-center justify-between",
119
- children: [/* @__PURE__ */ u("h2", {
120
- className: "text-lg font-semibold text-text-primary",
121
- children: b("pages.publisherDashboard.yourProducts", { defaultValue: "Your Products" })
122
- }), /* @__PURE__ */ d("button", {
123
- type: "button",
124
- onClick: () => v(`${y}/publisher/revenue`),
125
- className: "inline-flex cursor-pointer items-center gap-1.5 text-sm font-medium text-text-link hover:underline",
126
- children: [/* @__PURE__ */ u(o, { className: "size-4" }), "Revenue"]
127
- })]
128
- }), S ? /* @__PURE__ */ u("p", {
129
- role: "status",
130
- className: "text-sm text-text-muted",
131
- children: b("common.loading", { defaultValue: "Loading..." })
132
- }) : C ? /* @__PURE__ */ d("div", {
133
- role: "alert",
134
- className: "space-y-2",
135
- children: [/* @__PURE__ */ u("p", {
136
- className: "text-sm text-status-error-text",
137
- children: b("pages.publisherDashboard.failedToLoad", { defaultValue: "Failed to load publisher products." })
138
- }), /* @__PURE__ */ u("button", {
139
- type: "button",
140
- onClick: () => w(),
141
- className: "cursor-pointer rounded-lg bg-action-primary-bg px-3 py-1.5 text-xs font-semibold text-action-primary-text",
142
- children: "Retry"
143
- })]
144
- }) : x.length === 0 ? /* @__PURE__ */ u(h, {
145
- illustration: "empty-data",
146
- title: b("pages.publisherDashboard.noProductsTitle", { defaultValue: "No published products yet" }),
147
- description: b("pages.publisherDashboard.noProducts", { defaultValue: "No published products yet. Submit your first product to get started." }),
148
- action: /* @__PURE__ */ d("button", {
149
- type: "button",
150
- onClick: () => v(`${y}/publisher/submit`),
151
- className: "inline-flex cursor-pointer items-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-semibold text-action-primary-text hover:opacity-90",
152
- children: [/* @__PURE__ */ u(c, { className: "size-4" }), "Submit Product"]
153
- })
154
- }) : /* @__PURE__ */ u("ul", {
155
- className: "space-y-3",
156
- children: x.map((e) => /* @__PURE__ */ d("li", {
157
- className: "flex items-center justify-between rounded-lg border border-border-seam bg-bg-surface p-3 transition-[box-shadow,border-color] hover:border-border-strong hover:shadow-[var(--shadow-pop)]",
158
- children: [/* @__PURE__ */ d("button", {
159
- type: "button",
160
- onClick: () => v(`${y}/marketplace/product/${e.id}`),
161
- className: "flex flex-1 cursor-pointer items-center justify-between text-left",
162
- children: [/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("p", {
163
- className: "font-medium text-text-primary",
164
- children: e.name
165
- }), /* @__PURE__ */ u("p", {
166
- className: "text-xs text-text-muted",
167
- children: e.status
168
- })] }), /* @__PURE__ */ d("div", {
169
- className: "flex items-center gap-4 text-xs text-text-muted",
170
- children: [/* @__PURE__ */ d("span", {
171
- className: "inline-flex items-center gap-1",
172
- children: [/* @__PURE__ */ u(l, { className: "size-3.5" }), (e.rating ?? 0).toFixed(1)]
173
- }), /* @__PURE__ */ d("span", {
174
- className: "inline-flex items-center gap-1",
175
- children: [/* @__PURE__ */ u(a, { className: "size-3.5" }), e.downloads]
176
- })]
177
- })]
178
- }), /* @__PURE__ */ d("button", {
179
- type: "button",
180
- onClick: () => v(`${y}/publisher/product/${e.id}/reviews`),
181
- className: "ml-3 inline-flex cursor-pointer items-center gap-1 rounded-md px-2 py-1 text-xs font-medium text-text-link hover:bg-bg-sunken hover:underline",
182
- title: "View reviews",
183
- children: [/* @__PURE__ */ u(s, { className: "size-3.5" }), "Reviews"]
184
- })]
185
- }, e.id))
186
- })] })
187
- ]
188
- })
189
- })]
190
- });
191
- };
192
- //#endregion
193
- export { v as PublisherDashboardPage };
194
-
195
- //# sourceMappingURL=PublisherDashboardPage.js.map