@burdenoff/microfe-coolandlovely 2026.1031.2 → 2026.1101.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/coolandlovely/CoolAndLovelyRoot.d.ts.map +1 -1
- package/dist/coolandlovely/CoolAndLovelyRoot.js +16 -4
- package/dist/coolandlovely/CoolAndLovelyRoot.js.map +1 -1
- package/dist/coolandlovely/CoolAndLovelyRoutes.d.ts.map +1 -1
- package/dist/coolandlovely/CoolAndLovelyRoutes.js +19 -15
- package/dist/coolandlovely/CoolAndLovelyRoutes.js.map +1 -1
- package/dist/coolandlovely/components/ActivityTrail.js +1 -1
- package/dist/coolandlovely/components/ActivityTrail.js.map +1 -1
- package/dist/coolandlovely/components/ActorName.js.map +1 -1
- package/dist/coolandlovely/components/AddToCartPanel.js.map +1 -1
- package/dist/coolandlovely/components/AddToLookbookButton.js.map +1 -1
- package/dist/coolandlovely/components/BrandCard.js.map +1 -1
- package/dist/coolandlovely/components/BrandCover.js.map +1 -1
- package/dist/coolandlovely/components/BrandCreatorAvatars.js.map +1 -1
- package/dist/coolandlovely/components/CollaborationFeeCard.js.map +1 -1
- package/dist/coolandlovely/components/CollectionCard.js.map +1 -1
- package/dist/coolandlovely/components/ColourSwatchRow.js.map +1 -1
- package/dist/coolandlovely/components/Comments.js.map +1 -1
- package/dist/coolandlovely/components/EmptyState.js.map +1 -1
- package/dist/coolandlovely/components/FeedbackWidget.js.map +1 -1
- package/dist/coolandlovely/components/Field.js.map +1 -1
- package/dist/coolandlovely/components/FileImage.js.map +1 -1
- package/dist/coolandlovely/components/FollowButton.js.map +1 -1
- package/dist/coolandlovely/components/FulfilmentTimeline.js.map +1 -1
- package/dist/coolandlovely/components/ImageUploadField.js +3 -1
- package/dist/coolandlovely/components/ImageUploadField.js.map +1 -1
- package/dist/coolandlovely/components/LookCard.js.map +1 -1
- package/dist/coolandlovely/components/LookbookCard.js.map +1 -1
- package/dist/coolandlovely/components/MetricsCard.js.map +1 -1
- package/dist/coolandlovely/components/PageLayout.js.map +1 -1
- package/dist/coolandlovely/components/PayForOrder.js.map +1 -1
- package/dist/coolandlovely/components/RefundPanel.js +1 -1
- package/dist/coolandlovely/components/RefundPanel.js.map +1 -1
- package/dist/coolandlovely/components/ReturnRequests.js +1 -1
- package/dist/coolandlovely/components/ReturnRequests.js.map +1 -1
- package/dist/coolandlovely/components/ShopItemCard.js.map +1 -1
- package/dist/coolandlovely/components/StateViews.js.map +1 -1
- package/dist/coolandlovely/components/StatusBadge.js +1 -1
- package/dist/coolandlovely/components/StatusBadge.js.map +1 -1
- package/dist/coolandlovely/components/StepTracker.js.map +1 -1
- package/dist/coolandlovely/components/StockEditor.js.map +1 -1
- package/dist/coolandlovely/components/StoreListingCard.js.map +1 -1
- package/dist/coolandlovely/components/TagList.js.map +1 -1
- package/dist/coolandlovely/components/Thumbnail.js +1 -1
- package/dist/coolandlovely/components/Thumbnail.js.map +1 -1
- package/dist/coolandlovely/components/VisibilityChip.js.map +1 -1
- package/dist/coolandlovely/components/WardrobeItemCard.js.map +1 -1
- package/dist/coolandlovely/components/index.js +2 -1
- package/dist/coolandlovely/context/CoolAndLovelyContext.js +2 -1
- package/dist/coolandlovely/context/CoolAndLovelyContext.js.map +1 -1
- package/dist/coolandlovely/context/index.js +2 -1
- package/dist/coolandlovely/hooks/index.js +4 -3
- package/dist/coolandlovely/hooks/useActivity.d.ts +1 -1
- package/dist/coolandlovely/hooks/useActivity.d.ts.map +1 -1
- package/dist/coolandlovely/hooks/useActivity.js.map +1 -1
- package/dist/coolandlovely/hooks/useAssistantEntity.js.map +1 -1
- package/dist/coolandlovely/hooks/useBrandOrdersApi.d.ts +4 -4
- package/dist/coolandlovely/hooks/useBrandOrdersApi.d.ts.map +1 -1
- package/dist/coolandlovely/hooks/useBrandOrdersApi.js.map +1 -1
- package/dist/coolandlovely/hooks/useCatalogImport.js.map +1 -1
- package/dist/coolandlovely/hooks/useComments.d.ts +1 -1
- package/dist/coolandlovely/hooks/useComments.d.ts.map +1 -1
- package/dist/coolandlovely/hooks/useComments.js.map +1 -1
- package/dist/coolandlovely/hooks/useCommerceApi.d.ts +7 -7
- package/dist/coolandlovely/hooks/useCommerceApi.d.ts.map +1 -1
- package/dist/coolandlovely/hooks/useCommerceApi.js.map +1 -1
- package/dist/coolandlovely/hooks/useCoolAndLovelyApi.d.ts +24 -24
- package/dist/coolandlovely/hooks/useCoolAndLovelyApi.d.ts.map +1 -1
- package/dist/coolandlovely/hooks/useCoolAndLovelyApi.js.map +1 -1
- package/dist/coolandlovely/hooks/useEditorialApi.d.ts +95 -0
- package/dist/coolandlovely/hooks/useEditorialApi.d.ts.map +1 -0
- package/dist/coolandlovely/hooks/useEditorialApi.js +107 -0
- package/dist/coolandlovely/hooks/useEditorialApi.js.map +1 -0
- package/dist/coolandlovely/hooks/useFiles.js.map +1 -1
- package/dist/coolandlovely/hooks/useInventoryApi.d.ts +1 -1
- package/dist/coolandlovely/hooks/useInventoryApi.d.ts.map +1 -1
- package/dist/coolandlovely/hooks/useInventoryApi.js.map +1 -1
- package/dist/coolandlovely/hooks/useTr.js.map +1 -1
- package/dist/coolandlovely/index.js +6 -5
- package/dist/coolandlovely/pages/HomePage.js.map +1 -1
- package/dist/coolandlovely/pages/admin/AdminBrandsPage.js.map +1 -1
- package/dist/coolandlovely/pages/admin/AdminCollaborationsPage.js.map +1 -1
- package/dist/coolandlovely/pages/admin/AdminFeaturedItemsPage.js.map +1 -1
- package/dist/coolandlovely/pages/brands/BrandDetailPage.js.map +1 -1
- package/dist/coolandlovely/pages/brands/BrandFormPage.js.map +1 -1
- package/dist/coolandlovely/pages/brands/BrandsListPage.js.map +1 -1
- package/dist/coolandlovely/pages/brands/ImportCatalogPage.js.map +1 -1
- package/dist/coolandlovely/pages/collaborations/CollaborationDetailPage.js.map +1 -1
- package/dist/coolandlovely/pages/collaborations/CollaborationFormPage.js +1 -1
- package/dist/coolandlovely/pages/collaborations/CollaborationFormPage.js.map +1 -1
- package/dist/coolandlovely/pages/collaborations/CollaborationsListPage.js.map +1 -1
- package/dist/coolandlovely/pages/collections/CollectionDetailPage.js.map +1 -1
- package/dist/coolandlovely/pages/collections/CollectionFormPage.js.map +1 -1
- package/dist/coolandlovely/pages/collections/CollectionsListPage.js.map +1 -1
- package/dist/coolandlovely/pages/commerce/BrandOrdersPage.js.map +1 -1
- package/dist/coolandlovely/pages/commerce/CartPage.js.map +1 -1
- package/dist/coolandlovely/pages/commerce/CreatorEarningsPage.js.map +1 -1
- package/dist/coolandlovely/pages/commerce/OrdersPage.js.map +1 -1
- package/dist/coolandlovely/pages/discover/DiscoverPage.js +1 -1
- package/dist/coolandlovely/pages/discover/DiscoverPage.js.map +1 -1
- package/dist/coolandlovely/pages/editorial/EditorialPage.d.ts +2 -0
- package/dist/coolandlovely/pages/editorial/EditorialPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/editorial/EditorialPage.js +486 -0
- package/dist/coolandlovely/pages/editorial/EditorialPage.js.map +1 -0
- package/dist/coolandlovely/pages/items/StoreListedPieceView.js.map +1 -1
- package/dist/coolandlovely/pages/items/StyleItemDetailPage.js.map +1 -1
- package/dist/coolandlovely/pages/items/StyleItemFormPage.js.map +1 -1
- package/dist/coolandlovely/pages/items/StyleItemsListPage.js.map +1 -1
- package/dist/coolandlovely/pages/lookbooks/LookbookDetailPage.js.map +1 -1
- package/dist/coolandlovely/pages/lookbooks/LookbooksListPage.js.map +1 -1
- package/dist/coolandlovely/pages/looks/LookDetailPage.js.map +1 -1
- package/dist/coolandlovely/pages/looks/LookFormPage.js.map +1 -1
- package/dist/coolandlovely/pages/looks/LooksListPage.js.map +1 -1
- package/dist/coolandlovely/pages/profile/StyleProfilePage.js +1 -1
- package/dist/coolandlovely/pages/profile/StyleProfilePage.js.map +1 -1
- package/dist/coolandlovely/pages/trends/TrendsPage.js.map +1 -1
- package/dist/coolandlovely/pages/wardrobe/WardrobeFormPage.js.map +1 -1
- package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.js.map +1 -1
- package/dist/coolandlovely/store/coolandlovelyStore.js.map +1 -1
- package/dist/coolandlovely/store/index.js +2 -1
- package/dist/coolandlovely/types/commerce.d.ts.map +1 -1
- package/dist/coolandlovely/types/index.d.ts.map +1 -1
- package/dist/coolandlovely/utils/cn.js +1 -1
- package/dist/coolandlovely/utils/cn.js.map +1 -1
- package/dist/coolandlovely/utils/formatters.js.map +1 -1
- package/dist/coolandlovely/utils/icons.js.map +1 -1
- package/dist/coolandlovely/utils/index.js +2 -1
- package/dist/coolandlovely/utils/navigation.js.map +1 -1
- package/dist/coolandlovely/utils/paymentProviders.js +22 -22
- package/dist/coolandlovely/utils/paymentProviders.js.map +1 -1
- package/dist/coolandlovely/utils/sparkline.js +13 -15
- package/dist/coolandlovely/utils/sparkline.js.map +1 -1
- package/dist/node_modules/clsx/dist/clsx.js +1 -1
- package/dist/node_modules/clsx/dist/clsx.js.map +1 -1
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +225 -146
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -1
- package/dist/services/createSandboxAssistantTransport.js.map +1 -1
- package/dist/stories/DiscoverPage.stories.d.ts.map +1 -1
- package/dist/utils/pageContext.js +1 -1
- package/dist/utils/pageContext.js.map +1 -1
- package/package.json +6 -4
|
@@ -24,5 +24,6 @@ import "./StepTracker.js";
|
|
|
24
24
|
import "./BrandCreatorAvatars.js";
|
|
25
25
|
import "./ShopItemCard.js";
|
|
26
26
|
import "./ColourSwatchRow.js";
|
|
27
|
-
import "./FeedbackWidget.js";
|
|
27
|
+
import { FeedbackWidget as e } from "./FeedbackWidget.js";
|
|
28
28
|
import "./StoreListingCard.js";
|
|
29
|
+
export { e as FeedbackWidget };
|
|
@@ -11,7 +11,8 @@ function l() {
|
|
|
11
11
|
}
|
|
12
12
|
var u = ({ children: t, basePath: r, currentUser: a, tenantId: l, workspaceId: u, organizationId: d, apiGatewayUrl: f, authToken: p, workspaceToken: m }) => {
|
|
13
13
|
let h = o(), g = r || "/", _ = n((t) => e(g, t), [g]), v = n((t) => {
|
|
14
|
-
|
|
14
|
+
let n = e(g, t);
|
|
15
|
+
h(n);
|
|
15
16
|
}, [g, h]), y = i(() => ({
|
|
16
17
|
basePath: g,
|
|
17
18
|
navigate: void 0,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CoolAndLovelyContext.js","names":[],"sources":["../../../src/coolandlovely/context/CoolAndLovelyContext.tsx"],"sourcesContent":["/**\n * CoolAndLovely Context Provider\n * @module coolandlovely/context\n */\n\nimport type { FC, PropsWithChildren } from 'react';\nimport { createContext, useContext, useMemo, useCallback } from 'react';\nimport { MemoryRouter, useNavigate as useRouterNavigate } from 'react-router';\nimport type { CoolAndLovelyRootProps } from '../types';\nimport { joinPath } from '../utils/navigation';\n\n// ============================================================================\n// Context\n// ============================================================================\n\ninterface CoolAndLovelyContextValue extends Omit<\n CoolAndLovelyRootProps,\n 'registerNavItems' | 'registerFooterItems' | 'navigate'\n> {\n isStandalone: boolean;\n /** Shell's navigate function (only available in integrated mode) */\n navigate?: (path: string) => void;\n /** Navigate to a path relative to basePath */\n navigateTo: (relativePath: string) => void;\n /** Get the full path for a relative path */\n getPath: (relativePath: string) => string;\n}\n\nconst CoolAndLovelyContext = createContext<CoolAndLovelyContextValue | null>(null);\n\n// ============================================================================\n// Hook\n// ============================================================================\n\nexport function useCoolAndLovely(): CoolAndLovelyContextValue {\n const context = useContext(CoolAndLovelyContext);\n if (!context) {\n throw new Error('useCoolAndLovely must be used within a CoolAndLovelyProvider');\n }\n return context;\n}\n\n// ============================================================================\n// Provider Component\n// ============================================================================\n\ntype ProviderProps = Omit<CoolAndLovelyRootProps, 'registerNavItems' | 'registerFooterItems'> & {\n isStandalone: boolean;\n};\n\n/** Provider for standalone mode (has access to MemoryRouter) */\nconst StandaloneProviderInner: FC<PropsWithChildren<ProviderProps>> = ({\n children,\n basePath,\n currentUser,\n tenantId,\n workspaceId,\n organizationId,\n apiGatewayUrl,\n authToken,\n workspaceToken,\n}) => {\n const routerNavigate = useRouterNavigate();\n const effectiveBasePath = basePath || '/';\n\n const getPath = useCallback(\n (relativePath: string) => joinPath(effectiveBasePath, relativePath),\n [effectiveBasePath]\n );\n\n const navigateTo = useCallback(\n (relativePath: string) => {\n const fullPath = joinPath(effectiveBasePath, relativePath);\n routerNavigate(fullPath);\n },\n [effectiveBasePath, routerNavigate]\n );\n\n const contextValue = useMemo<CoolAndLovelyContextValue>(\n () => ({\n basePath: effectiveBasePath,\n navigate: undefined,\n currentUser,\n tenantId,\n workspaceId,\n organizationId,\n apiGatewayUrl,\n authToken,\n workspaceToken,\n isStandalone: true,\n navigateTo,\n getPath,\n }),\n [\n effectiveBasePath,\n currentUser,\n tenantId,\n workspaceId,\n organizationId,\n apiGatewayUrl,\n authToken,\n workspaceToken,\n navigateTo,\n getPath,\n ]\n );\n\n return (\n <CoolAndLovelyContext.Provider value={contextValue}>{children}</CoolAndLovelyContext.Provider>\n );\n};\n\n/** Provider for integrated mode (shell provides navigate) */\nconst IntegratedProviderInner: FC<\n PropsWithChildren<ProviderProps & { navigate: (path: string) => void }>\n> = ({\n children,\n basePath,\n navigate,\n currentUser,\n tenantId,\n workspaceId,\n organizationId,\n apiGatewayUrl,\n authToken,\n workspaceToken,\n}) => {\n const effectiveBasePath = basePath || '/';\n\n const getPath = useCallback(\n (relativePath: string) => joinPath(effectiveBasePath, relativePath),\n [effectiveBasePath]\n );\n\n const navigateTo = useCallback(\n (relativePath: string) => {\n const fullPath = joinPath(effectiveBasePath, relativePath);\n navigate(fullPath);\n },\n [effectiveBasePath, navigate]\n );\n\n const contextValue = useMemo<CoolAndLovelyContextValue>(\n () => ({\n basePath: effectiveBasePath,\n navigate,\n currentUser,\n tenantId,\n workspaceId,\n organizationId,\n apiGatewayUrl,\n authToken,\n workspaceToken,\n isStandalone: false,\n navigateTo,\n getPath,\n }),\n [\n effectiveBasePath,\n navigate,\n currentUser,\n tenantId,\n workspaceId,\n organizationId,\n apiGatewayUrl,\n authToken,\n workspaceToken,\n navigateTo,\n getPath,\n ]\n );\n\n return (\n <CoolAndLovelyContext.Provider value={contextValue}>{children}</CoolAndLovelyContext.Provider>\n );\n};\n\nexport const CoolAndLovelyProvider: FC<PropsWithChildren<CoolAndLovelyRootProps>> = (props) => {\n const { children, navigate } = props;\n // Standalone mode: no navigate function provided (MFE manages its own router)\n // Integrated mode: navigate function provided by shell (shell provides router)\n const isStandalone = !navigate;\n\n if (isStandalone) {\n return (\n <MemoryRouter>\n <StandaloneProviderInner {...props} isStandalone={true}>\n {children}\n </StandaloneProviderInner>\n </MemoryRouter>\n );\n }\n\n return (\n <IntegratedProviderInner {...props} navigate={navigate} isStandalone={false}>\n {children}\n </IntegratedProviderInner>\n );\n};\n"],"mappings":";;;;;AA4BA,IAAM,IAAuB,EAAgD,
|
|
1
|
+
{"version":3,"file":"CoolAndLovelyContext.js","names":[],"sources":["../../../src/coolandlovely/context/CoolAndLovelyContext.tsx"],"sourcesContent":["/**\n * CoolAndLovely Context Provider\n * @module coolandlovely/context\n */\n\nimport type { FC, PropsWithChildren } from 'react';\nimport { createContext, useContext, useMemo, useCallback } from 'react';\nimport { MemoryRouter, useNavigate as useRouterNavigate } from 'react-router';\nimport type { CoolAndLovelyRootProps } from '../types';\nimport { joinPath } from '../utils/navigation';\n\n// ============================================================================\n// Context\n// ============================================================================\n\ninterface CoolAndLovelyContextValue extends Omit<\n CoolAndLovelyRootProps,\n 'registerNavItems' | 'registerFooterItems' | 'navigate'\n> {\n isStandalone: boolean;\n /** Shell's navigate function (only available in integrated mode) */\n navigate?: (path: string) => void;\n /** Navigate to a path relative to basePath */\n navigateTo: (relativePath: string) => void;\n /** Get the full path for a relative path */\n getPath: (relativePath: string) => string;\n}\n\nconst CoolAndLovelyContext = createContext<CoolAndLovelyContextValue | null>(null);\n\n// ============================================================================\n// Hook\n// ============================================================================\n\nexport function useCoolAndLovely(): CoolAndLovelyContextValue {\n const context = useContext(CoolAndLovelyContext);\n if (!context) {\n throw new Error('useCoolAndLovely must be used within a CoolAndLovelyProvider');\n }\n return context;\n}\n\n// ============================================================================\n// Provider Component\n// ============================================================================\n\ntype ProviderProps = Omit<CoolAndLovelyRootProps, 'registerNavItems' | 'registerFooterItems'> & {\n isStandalone: boolean;\n};\n\n/** Provider for standalone mode (has access to MemoryRouter) */\nconst StandaloneProviderInner: FC<PropsWithChildren<ProviderProps>> = ({\n children,\n basePath,\n currentUser,\n tenantId,\n workspaceId,\n organizationId,\n apiGatewayUrl,\n authToken,\n workspaceToken,\n}) => {\n const routerNavigate = useRouterNavigate();\n const effectiveBasePath = basePath || '/';\n\n const getPath = useCallback(\n (relativePath: string) => joinPath(effectiveBasePath, relativePath),\n [effectiveBasePath]\n );\n\n const navigateTo = useCallback(\n (relativePath: string) => {\n const fullPath = joinPath(effectiveBasePath, relativePath);\n routerNavigate(fullPath);\n },\n [effectiveBasePath, routerNavigate]\n );\n\n const contextValue = useMemo<CoolAndLovelyContextValue>(\n () => ({\n basePath: effectiveBasePath,\n navigate: undefined,\n currentUser,\n tenantId,\n workspaceId,\n organizationId,\n apiGatewayUrl,\n authToken,\n workspaceToken,\n isStandalone: true,\n navigateTo,\n getPath,\n }),\n [\n effectiveBasePath,\n currentUser,\n tenantId,\n workspaceId,\n organizationId,\n apiGatewayUrl,\n authToken,\n workspaceToken,\n navigateTo,\n getPath,\n ]\n );\n\n return (\n <CoolAndLovelyContext.Provider value={contextValue}>{children}</CoolAndLovelyContext.Provider>\n );\n};\n\n/** Provider for integrated mode (shell provides navigate) */\nconst IntegratedProviderInner: FC<\n PropsWithChildren<ProviderProps & { navigate: (path: string) => void }>\n> = ({\n children,\n basePath,\n navigate,\n currentUser,\n tenantId,\n workspaceId,\n organizationId,\n apiGatewayUrl,\n authToken,\n workspaceToken,\n}) => {\n const effectiveBasePath = basePath || '/';\n\n const getPath = useCallback(\n (relativePath: string) => joinPath(effectiveBasePath, relativePath),\n [effectiveBasePath]\n );\n\n const navigateTo = useCallback(\n (relativePath: string) => {\n const fullPath = joinPath(effectiveBasePath, relativePath);\n navigate(fullPath);\n },\n [effectiveBasePath, navigate]\n );\n\n const contextValue = useMemo<CoolAndLovelyContextValue>(\n () => ({\n basePath: effectiveBasePath,\n navigate,\n currentUser,\n tenantId,\n workspaceId,\n organizationId,\n apiGatewayUrl,\n authToken,\n workspaceToken,\n isStandalone: false,\n navigateTo,\n getPath,\n }),\n [\n effectiveBasePath,\n navigate,\n currentUser,\n tenantId,\n workspaceId,\n organizationId,\n apiGatewayUrl,\n authToken,\n workspaceToken,\n navigateTo,\n getPath,\n ]\n );\n\n return (\n <CoolAndLovelyContext.Provider value={contextValue}>{children}</CoolAndLovelyContext.Provider>\n );\n};\n\nexport const CoolAndLovelyProvider: FC<PropsWithChildren<CoolAndLovelyRootProps>> = (props) => {\n const { children, navigate } = props;\n // Standalone mode: no navigate function provided (MFE manages its own router)\n // Integrated mode: navigate function provided by shell (shell provides router)\n const isStandalone = !navigate;\n\n if (isStandalone) {\n return (\n <MemoryRouter>\n <StandaloneProviderInner {...props} isStandalone={true}>\n {children}\n </StandaloneProviderInner>\n </MemoryRouter>\n );\n }\n\n return (\n <IntegratedProviderInner {...props} navigate={navigate} isStandalone={false}>\n {children}\n </IntegratedProviderInner>\n );\n};\n"],"mappings":";;;;;AA4BA,IAAM,IAAuB,EAAgD,IAAI;AAMjF,SAAgB,IAA8C;CAC5D,IAAM,IAAU,EAAW,CAAoB;CAC/C,IAAI,CAAC,GACH,MAAU,MAAM,8DAA8D;CAEhF,OAAO;AACT;AAWA,IAAM,KAAiE,EACrE,aACA,aACA,gBACA,aACA,gBACA,mBACA,kBACA,cACA,wBACI;CACJ,IAAM,IAAiB,EAAkB,GACnC,IAAoB,KAAY,KAEhC,IAAU,GACb,MAAyB,EAAS,GAAmB,CAAY,GAClE,CAAC,CAAiB,CACpB,GAEM,IAAa,GAChB,MAAyB;EACxB,IAAM,IAAW,EAAS,GAAmB,CAAY;EACzD,EAAe,CAAQ;CACzB,GACA,CAAC,GAAmB,CAAc,CACpC,GAEM,IAAe,SACZ;EACL,UAAU;EACV,UAAU,KAAA;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA,cAAc;EACd;EACA;CACF,IACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CACF;CAEA,OACE,kBAAC,EAAqB,UAAtB;EAA+B,OAAO;EAAe;CAAwC,CAAA;AAEjG,GAGM,KAED,EACH,aACA,aACA,aACA,gBACA,aACA,gBACA,mBACA,kBACA,cACA,wBACI;CACJ,IAAM,IAAoB,KAAY,KAEhC,IAAU,GACb,MAAyB,EAAS,GAAmB,CAAY,GAClE,CAAC,CAAiB,CACpB,GAEM,IAAa,GAChB,MAAyB;EAExB,EADiB,EAAS,GAAmB,CACpC,CAAQ;CACnB,GACA,CAAC,GAAmB,CAAQ,CAC9B,GAEM,IAAe,SACZ;EACL,UAAU;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,cAAc;EACd;EACA;CACF,IACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CACF;CAEA,OACE,kBAAC,EAAqB,UAAtB;EAA+B,OAAO;EAAe;CAAwC,CAAA;AAEjG,GAEa,KAAwE,MAAU;CAC7F,IAAM,EAAE,aAAU,gBAAa;CAe/B,OAZsB,IAapB,kBAAC,GAAD;EAAyB,GAAI;EAAiB;EAAU,cAAc;EACnE;CACsB,CAAA,IAXvB,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;EAAyB,GAAI;EAAO,cAAc;EAC/C;CACsB,CAAA,EACb,CAAA;AASpB"}
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import "./CoolAndLovelyContext.js";
|
|
1
|
+
import { CoolAndLovelyProvider as e, useCoolAndLovely as t } from "./CoolAndLovelyContext.js";
|
|
2
|
+
export { e as CoolAndLovelyProvider, t as useCoolAndLovely };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import "./useCoolAndLovelyApi.js";
|
|
1
|
+
import { useAddLookbookEntry as e, useApproveBrand as t, useArchiveCollection as n, useArchiveStyleItem as r, useBrand as i, useBrands as a, useCollaboration as o, useCollaborations as s, useCollection as c, useCollections as l, useCreateBrand as u, useCreateCollaboration as d, useCreateCollection as f, useCreateLook as p, useCreateLookbook as m, useCreateStyleItem as h, useCreateWardrobeItem as g, useDeleteCollaboration as _, useDeleteLook as v, useDeleteLookbook as y, useFeatureStyleItem as b, useLikeLook as x, useLogWardrobeWear as S, useLook as C, useLookbook as w, useLookbooks as T, useLooks as E, useLooksWithItems as D, useMyFollowing as O, useMyStyleProfile as k, usePublishCollection as A, usePublishLook as j, useRejectBrand as M, useRemoveLookbookEntry as N, useRemoveWardrobeItem as P, useReviewCollaboration as F, useSaveLook as I, useSearchLooks as L, useSearchStyleItems as R, useStyleItem as z, useStyleItems as B, useStyleProfileByOwner as V, useTransitionBrand as H, useTransitionCollaboration as U, useUnfeatureStyleItem as W, useUnlikeLook as G, useUnsaveLook as K, useUpdateBrand as q, useUpdateCollaboration as J, useUpdateCollection as Y, useUpdateLook as X, useUpdateStyleItem as Z, useUpsertStyleProfile as Q, useWardrobeItems as $ } from "./useCoolAndLovelyApi.js";
|
|
2
2
|
import "./useFiles.js";
|
|
3
3
|
import "./useComments.js";
|
|
4
4
|
import "./useActivity.js";
|
|
5
|
-
import "./useAssistantEntity.js";
|
|
6
|
-
import "./useTr.js";
|
|
5
|
+
import { useAssistantEntityName as ee } from "./useAssistantEntity.js";
|
|
6
|
+
import { useTr as te } from "./useTr.js";
|
|
7
|
+
export { e as useAddLookbookEntry, t as useApproveBrand, n as useArchiveCollection, r as useArchiveStyleItem, ee as useAssistantEntityName, i as useBrand, a as useBrands, o as useCollaboration, s as useCollaborations, c as useCollection, l as useCollections, u as useCreateBrand, d as useCreateCollaboration, f as useCreateCollection, p as useCreateLook, m as useCreateLookbook, h as useCreateStyleItem, g as useCreateWardrobeItem, _ as useDeleteCollaboration, v as useDeleteLook, y as useDeleteLookbook, b as useFeatureStyleItem, x as useLikeLook, S as useLogWardrobeWear, C as useLook, w as useLookbook, T as useLookbooks, E as useLooks, D as useLooksWithItems, O as useMyFollowing, k as useMyStyleProfile, A as usePublishCollection, j as usePublishLook, M as useRejectBrand, N as useRemoveLookbookEntry, P as useRemoveWardrobeItem, F as useReviewCollaboration, I as useSaveLook, L as useSearchLooks, R as useSearchStyleItems, z as useStyleItem, B as useStyleItems, V as useStyleProfileByOwner, te as useTr, H as useTransitionBrand, U as useTransitionCollaboration, W as useUnfeatureStyleItem, G as useUnlikeLook, K as useUnsaveLook, q as useUpdateBrand, J as useUpdateCollaboration, Y as useUpdateCollection, X as useUpdateLook, Z as useUpdateStyleItem, Q as useUpsertStyleProfile, $ as useWardrobeItems };
|
|
@@ -35,5 +35,5 @@ export interface CooActivityEntry {
|
|
|
35
35
|
* scopeType: "wspace")` — a member without that permission gets an error from
|
|
36
36
|
* the gateway, which callers surface honestly rather than hiding.
|
|
37
37
|
*/
|
|
38
|
-
export declare const useEntityActivity: (resourceType: string, resourceId: string | undefined, limit?: number) => import('@tanstack/react-query').UseQueryResult<
|
|
38
|
+
export declare const useEntityActivity: (resourceType: string, resourceId: string | undefined, limit?: number) => import('@tanstack/react-query').UseQueryResult<CooActivityEntry[], Error>;
|
|
39
39
|
//# sourceMappingURL=useActivity.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useActivity.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/hooks/useActivity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AASH,4EAA4E;AAC5E,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAqCD;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAC5B,cAAc,MAAM,EACpB,YAAY,MAAM,GAAG,SAAS,EAC9B,cAAU,
|
|
1
|
+
{"version":3,"file":"useActivity.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/hooks/useActivity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AASH,4EAA4E;AAC5E,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAqCD;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAC5B,cAAc,MAAM,EACpB,YAAY,MAAM,GAAG,SAAS,EAC9B,cAAU,8EAiBX,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useActivity.js","names":[],"sources":["../../../src/coolandlovely/hooks/useActivity.ts"],"sourcesContent":["/**\n * Audit-trail hooks — activity via wspace-activity-svc (NO new table).\n * @module coolandlovely/hooks\n *\n * CoolAndLovely does NOT own an audit table. Every `coo*` mutation is already\n * recorded by the svc's mutation-audit plugin\n * (`wspace-coolandlovely-svc/src/plugins/mutation-audit-plugin.ts`) through\n * be-sdk `trackOperation`, which writes an `ActivityLog` row on\n * wspace-activity-svc carrying:\n *\n * action — the plugin's `eventName`, e.g. `coolandlovely.brand_transitioned`\n * description — `\"<action> <resourceType>: <fieldName>\"`\n * resourceType — e.g. `coolandlovely-brand`\n * resourceId — the affected record's id\n * userId — the acting actor\n *\n * This hook is purely the read surface over those rows (`getActivities`,\n * federated on the workspace supergraph). Nothing is synthesised: when the\n * service has no rows for a record, callers render an empty state.\n */\n\nimport { useQuery } from '@tanstack/react-query';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\n\nimport { useCoolAndLovely } from '../context';\n\nconst QK = 'coolandlovely-activity';\n\n/** A single audit entry as surfaced in the MFE (scalar-only projection). */\nexport interface CooActivityEntry {\n id: string;\n action: string;\n description: string | null;\n resourceType: string | null;\n resourceId: string | null;\n userId: string;\n timestamp: string;\n}\n\nconst GET_ACTIVITIES = `\n query CooEntityActivity($filter: ActivityLogFilter) {\n getActivities(filter: $filter) {\n id\n action\n description\n resourceType\n resourceId\n userId\n timestamp\n }\n }\n`;\n\nconst activityFetch = async <TData>(\n query: string,\n variables: Record<string, unknown>,\n baseUrl?: string\n): Promise<TData> => {\n const response = await graphqlFetch<TData>({\n gateway: 'workspace',\n baseUrl,\n query,\n variables,\n workspaceToken: true,\n });\n if (response.errors?.length) {\n throw new Error(response.errors[0]?.message ?? 'Activity request failed');\n }\n if (!response.data) {\n throw new Error('Activity response did not include data');\n }\n return response.data;\n};\n\n/**\n * Audit entries for one record, newest first.\n *\n * `getActivities` is `@rbac(action: \"read\", resource: \"activity-log\",\n * scopeType: \"wspace\")` — a member without that permission gets an error from\n * the gateway, which callers surface honestly rather than hiding.\n */\nexport const useEntityActivity = (\n resourceType: string,\n resourceId: string | undefined,\n limit = 20\n) => {\n const { apiGatewayUrl, workspaceId } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, resourceType, resourceId, limit],\n enabled: Boolean(resourceId) && Boolean(workspaceId),\n queryFn: async (): Promise<CooActivityEntry[]> => {\n const data = await activityFetch<{ getActivities: CooActivityEntry[] }>(\n GET_ACTIVITIES,\n { filter: { workspaceId, resourceType, resourceId, limit } },\n apiGatewayUrl\n );\n return [...data.getActivities].sort(\n (a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()\n );\n },\n });\n};\n"],"mappings":";;;;;AA0BA,IAAM,IAAK,0BAaL,IAAiB,iOAcjB,IAAgB,OACpB,GACA,GACA,MACmB;CACnB,IAAM,IAAW,MAAM,EAAoB;EACzC,SAAS;EACT;EACA;EACA;EACA,gBAAgB;
|
|
1
|
+
{"version":3,"file":"useActivity.js","names":[],"sources":["../../../src/coolandlovely/hooks/useActivity.ts"],"sourcesContent":["/**\n * Audit-trail hooks — activity via wspace-activity-svc (NO new table).\n * @module coolandlovely/hooks\n *\n * CoolAndLovely does NOT own an audit table. Every `coo*` mutation is already\n * recorded by the svc's mutation-audit plugin\n * (`wspace-coolandlovely-svc/src/plugins/mutation-audit-plugin.ts`) through\n * be-sdk `trackOperation`, which writes an `ActivityLog` row on\n * wspace-activity-svc carrying:\n *\n * action — the plugin's `eventName`, e.g. `coolandlovely.brand_transitioned`\n * description — `\"<action> <resourceType>: <fieldName>\"`\n * resourceType — e.g. `coolandlovely-brand`\n * resourceId — the affected record's id\n * userId — the acting actor\n *\n * This hook is purely the read surface over those rows (`getActivities`,\n * federated on the workspace supergraph). Nothing is synthesised: when the\n * service has no rows for a record, callers render an empty state.\n */\n\nimport { useQuery } from '@tanstack/react-query';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\n\nimport { useCoolAndLovely } from '../context';\n\nconst QK = 'coolandlovely-activity';\n\n/** A single audit entry as surfaced in the MFE (scalar-only projection). */\nexport interface CooActivityEntry {\n id: string;\n action: string;\n description: string | null;\n resourceType: string | null;\n resourceId: string | null;\n userId: string;\n timestamp: string;\n}\n\nconst GET_ACTIVITIES = `\n query CooEntityActivity($filter: ActivityLogFilter) {\n getActivities(filter: $filter) {\n id\n action\n description\n resourceType\n resourceId\n userId\n timestamp\n }\n }\n`;\n\nconst activityFetch = async <TData>(\n query: string,\n variables: Record<string, unknown>,\n baseUrl?: string\n): Promise<TData> => {\n const response = await graphqlFetch<TData>({\n gateway: 'workspace',\n baseUrl,\n query,\n variables,\n workspaceToken: true,\n });\n if (response.errors?.length) {\n throw new Error(response.errors[0]?.message ?? 'Activity request failed');\n }\n if (!response.data) {\n throw new Error('Activity response did not include data');\n }\n return response.data;\n};\n\n/**\n * Audit entries for one record, newest first.\n *\n * `getActivities` is `@rbac(action: \"read\", resource: \"activity-log\",\n * scopeType: \"wspace\")` — a member without that permission gets an error from\n * the gateway, which callers surface honestly rather than hiding.\n */\nexport const useEntityActivity = (\n resourceType: string,\n resourceId: string | undefined,\n limit = 20\n) => {\n const { apiGatewayUrl, workspaceId } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, resourceType, resourceId, limit],\n enabled: Boolean(resourceId) && Boolean(workspaceId),\n queryFn: async (): Promise<CooActivityEntry[]> => {\n const data = await activityFetch<{ getActivities: CooActivityEntry[] }>(\n GET_ACTIVITIES,\n { filter: { workspaceId, resourceType, resourceId, limit } },\n apiGatewayUrl\n );\n return [...data.getActivities].sort(\n (a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()\n );\n },\n });\n};\n"],"mappings":";;;;;AA0BA,IAAM,IAAK,0BAaL,IAAiB,iOAcjB,IAAgB,OACpB,GACA,GACA,MACmB;CACnB,IAAM,IAAW,MAAM,EAAoB;EACzC,SAAS;EACT;EACA;EACA;EACA,gBAAgB;CAClB,CAAC;CACD,IAAI,EAAS,QAAQ,QACnB,MAAU,MAAM,EAAS,OAAO,EAAE,EAAE,WAAW,yBAAyB;CAE1E,IAAI,CAAC,EAAS,MACZ,MAAU,MAAM,wCAAwC;CAE1D,OAAO,EAAS;AAClB,GASa,KACX,GACA,GACA,IAAQ,OACL;CACH,IAAM,EAAE,kBAAe,mBAAgB,EAAiB;CACxD,OAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAc;GAAY;EAAK;EAC9C,SAAS,EAAQ,KAAe,EAAQ;EACxC,SAAS,YAMA,CAAC,IAAG,MALQ,EACjB,GACA,EAAE,QAAQ;GAAE;GAAa;GAAc;GAAY;EAAM,EAAE,GAC3D,CACF,EAAA,CACgB,aAAa,CAAC,CAAC,MAC5B,GAAG,MAAM,IAAI,KAAK,EAAE,SAAS,CAAC,CAAC,QAAQ,IAAI,IAAI,KAAK,EAAE,SAAS,CAAC,CAAC,QAAQ,CAC5E;CAEJ,CAAC;AACH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAssistantEntity.js","names":[],"sources":["../../../src/coolandlovely/hooks/useAssistantEntity.ts"],"sourcesContent":["/**\n * Assistant screen-context hook.\n * @module coolandlovely/hooks\n *\n * The floating assistant already receives `entityType` / `entityId`, both\n * resolved from the URL. Neither tells the model WHAT the shopper is looking\n * at, so \"publish this storefront\" or \"what collections is this in\" forces the\n * assistant to echo a UUID back at a human.\n *\n * `entityName` is one of the agent's allowed context keys\n * (`~/products/wspace/sandbox/ai-assistant/src/context-loader.ts`), but nothing\n * in this product ever sent it. Detail pages call this hook with the name from\n * their own loaded record — no extra request, no invented label — and it is\n * withdrawn again on unmount.\n */\n\nimport { useEffect } from 'react';\n\nimport { clearActiveEntityName, setActiveEntityName } from '../../utils/pageContext';\n\n/**\n * Publish the current entity's display name to the assistant page context.\n *\n * Safe to call before the record has loaded: a missing id or name simply\n * publishes nothing, so the assistant falls back to the id-only context it\n * gets today rather than receiving a placeholder.\n */\nexport function useAssistantEntityName(\n entityId: string | undefined,\n entityName: string | null | undefined\n): void {\n useEffect(() => {\n if (!entityId || !entityName) return;\n setActiveEntityName(entityId, entityName);\n return () => clearActiveEntityName(entityId);\n }, [entityId, entityName]);\n}\n"],"mappings":";;;AA2BA,SAAgB,EACd,GACA,GACM;
|
|
1
|
+
{"version":3,"file":"useAssistantEntity.js","names":[],"sources":["../../../src/coolandlovely/hooks/useAssistantEntity.ts"],"sourcesContent":["/**\n * Assistant screen-context hook.\n * @module coolandlovely/hooks\n *\n * The floating assistant already receives `entityType` / `entityId`, both\n * resolved from the URL. Neither tells the model WHAT the shopper is looking\n * at, so \"publish this storefront\" or \"what collections is this in\" forces the\n * assistant to echo a UUID back at a human.\n *\n * `entityName` is one of the agent's allowed context keys\n * (`~/products/wspace/sandbox/ai-assistant/src/context-loader.ts`), but nothing\n * in this product ever sent it. Detail pages call this hook with the name from\n * their own loaded record — no extra request, no invented label — and it is\n * withdrawn again on unmount.\n */\n\nimport { useEffect } from 'react';\n\nimport { clearActiveEntityName, setActiveEntityName } from '../../utils/pageContext';\n\n/**\n * Publish the current entity's display name to the assistant page context.\n *\n * Safe to call before the record has loaded: a missing id or name simply\n * publishes nothing, so the assistant falls back to the id-only context it\n * gets today rather than receiving a placeholder.\n */\nexport function useAssistantEntityName(\n entityId: string | undefined,\n entityName: string | null | undefined\n): void {\n useEffect(() => {\n if (!entityId || !entityName) return;\n setActiveEntityName(entityId, entityName);\n return () => clearActiveEntityName(entityId);\n }, [entityId, entityName]);\n}\n"],"mappings":";;;AA2BA,SAAgB,EACd,GACA,GACM;CACN,QAAgB;EACV,OAAC,KAAY,CAAC,IAElB,OADA,EAAoB,GAAU,CAAU,SAC3B,EAAsB,CAAQ;CAC7C,GAAG,CAAC,GAAU,CAAU,CAAC;AAC3B"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { CooApproveReturnRequestInput, CooBrandOrder, CooBrandOrderConnection, CooBrandOrderSummary, CooDeclineReturnRequestInput, CooFulfilmentStatus, CooRefundBrandOrderInput, CooReturnRequestConnection, CooReturnRequestStatus, CooUpdateOrderFulfilmentInput } from '../types';
|
|
2
2
|
|
|
3
|
-
export declare const useBrandOrders: (brandId: string | undefined, fulfilmentStatus?: CooFulfilmentStatus) => import('@tanstack/react-query').UseQueryResult<
|
|
4
|
-
export declare const useBrandOrderSummary: (brandId: string | undefined) => import('@tanstack/react-query').UseQueryResult<
|
|
5
|
-
export declare const useBrandOrder: (brandId: string | undefined, id: string | undefined) => import('@tanstack/react-query').UseQueryResult<
|
|
3
|
+
export declare const useBrandOrders: (brandId: string | undefined, fulfilmentStatus?: CooFulfilmentStatus) => import('@tanstack/react-query').UseQueryResult<CooBrandOrderConnection, Error>;
|
|
4
|
+
export declare const useBrandOrderSummary: (brandId: string | undefined) => import('@tanstack/react-query').UseQueryResult<CooBrandOrderSummary, Error>;
|
|
5
|
+
export declare const useBrandOrder: (brandId: string | undefined, id: string | undefined) => import('@tanstack/react-query').UseQueryResult<CooBrandOrder | null, Error>;
|
|
6
6
|
export declare const useUpdateOrderFulfilment: () => import('@tanstack/react-query').UseMutationResult<CooBrandOrder, Error, CooUpdateOrderFulfilmentInput, unknown>;
|
|
7
7
|
/**
|
|
8
8
|
* Refund the brand's pieces of an order (BOFF-9702). global-billing returns the money to the
|
|
@@ -12,7 +12,7 @@ export declare const useUpdateOrderFulfilment: () => import('@tanstack/react-que
|
|
|
12
12
|
*/
|
|
13
13
|
export declare const useRefundBrandOrder: () => import('@tanstack/react-query').UseMutationResult<CooBrandOrder, Error, CooRefundBrandOrderInput, unknown>;
|
|
14
14
|
/** The brand's return requests, newest first, optionally by status (BOFF-9900). */
|
|
15
|
-
export declare const useBrandReturnRequests: (brandId: string | undefined, status?: CooReturnRequestStatus) => import('@tanstack/react-query').UseQueryResult<
|
|
15
|
+
export declare const useBrandReturnRequests: (brandId: string | undefined, status?: CooReturnRequestStatus) => import('@tanstack/react-query').UseQueryResult<CooReturnRequestConnection, Error>;
|
|
16
16
|
/**
|
|
17
17
|
* Approve a shopper's return (BOFF-9900): refunds the brand's pieces through the brand refund and
|
|
18
18
|
* marks the request approved. On an error the order is refetched so a failed refund shows why.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useBrandOrdersApi.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/hooks/useBrandOrdersApi.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EACV,4BAA4B,EAC5B,aAAa,EACb,uBAAuB,EACvB,oBAAoB,EACpB,4BAA4B,EAC5B,mBAAmB,EACnB,wBAAwB,EACxB,0BAA0B,EAC1B,sBAAsB,EACtB,6BAA6B,EAC9B,MAAM,UAAU,CAAC;AAkBlB,eAAO,MAAM,cAAc,GACzB,SAAS,MAAM,GAAG,SAAS,EAC3B,mBAAmB,mBAAmB,
|
|
1
|
+
{"version":3,"file":"useBrandOrdersApi.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/hooks/useBrandOrdersApi.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EACV,4BAA4B,EAC5B,aAAa,EACb,uBAAuB,EACvB,oBAAoB,EACpB,4BAA4B,EAC5B,mBAAmB,EACnB,wBAAwB,EACxB,0BAA0B,EAC1B,sBAAsB,EACtB,6BAA6B,EAC9B,MAAM,UAAU,CAAC;AAkBlB,eAAO,MAAM,cAAc,GACzB,SAAS,MAAM,GAAG,SAAS,EAC3B,mBAAmB,mBAAmB,mFAoBvC,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,SAAS,MAAM,GAAG,SAAS,gFAkB/D,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,GAAG,SAAS,EAAE,IAAI,MAAM,GAAG,SAAS,gFAchF,CAAC;AAEF,eAAO,MAAM,wBAAwB,uHAoBpC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,kHAoC/B,CAAC;AAEF,mFAAmF;AACnF,eAAO,MAAM,sBAAsB,GACjC,SAAS,MAAM,GAAG,SAAS,EAC3B,SAAS,sBAAsB,sFAoBhC,CAAC;AAaF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,sHAiBnC,CAAC;AAEF,2EAA2E;AAC3E,eAAO,MAAM,uBAAuB,sHAgBnC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useBrandOrdersApi.js","names":[],"sources":["../../../src/coolandlovely/hooks/useBrandOrdersApi.ts"],"sourcesContent":["/**\n * Brand order hooks (BOFF-9636)\n * @module coolandlovely/hooks\n *\n * React Query layer over the brand-side order fields of `wspace-coolandlovely-svc`: the paid\n * orders that contain a brand's pieces (only that brand's lines), counts per fulfilment state,\n * and the fulfilment mutation (confirm, ship with tracking, mark delivered). Also the brand's\n * refunds (BOFF-9702) and the shopper return requests it approves or declines (BOFF-9900).\n */\n\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\n\nimport { useCoolAndLovely } from '../context';\nimport type {\n CooApproveReturnRequestInput,\n CooBrandOrder,\n CooBrandOrderConnection,\n CooBrandOrderSummary,\n CooDeclineReturnRequestInput,\n CooFulfilmentStatus,\n CooRefundBrandOrderInput,\n CooReturnRequestConnection,\n CooReturnRequestStatus,\n CooUpdateOrderFulfilmentInput,\n} from '../types';\nimport { FULFILMENT_FIELDS, REFUND_FIELDS, RETURN_REQUEST_FIELDS } from './useCommerceApi';\nimport { coolQuery } from './useCoolAndLovelyApi';\n\nconst QK = 'coolandlovely';\n\nconst BRAND_ORDER_FIELDS = `\n id orderNumber status brandId currency brandSubtotal itemCount\n shippingName shippingAddress buyerNote paidAt createdAt\n items {\n id styleItemId brandId name sku image { id } size colour unitPrice quantity lineTotal\n lookId isCreatorAttributed stockTracked\n }\n fulfilment { ${FULFILMENT_FIELDS} }\n refund { ${REFUND_FIELDS} }\n returnRequest { ${RETURN_REQUEST_FIELDS} }\n`;\n\nexport const useBrandOrders = (\n brandId: string | undefined,\n fulfilmentStatus?: CooFulfilmentStatus\n) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'brand-orders', brandId, fulfilmentStatus ?? 'ALL'],\n enabled: !!brandId,\n queryFn: async () => {\n const data = await coolQuery<{ cooBrandOrders: CooBrandOrderConnection }>(\n `query CooBrandOrders($brandId: ID!, $fulfilmentStatus: CooFulfilmentStatus, $pagination: PaginationInput) {\n cooBrandOrders(brandId: $brandId, fulfilmentStatus: $fulfilmentStatus, pagination: $pagination) {\n items { ${BRAND_ORDER_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n { brandId, fulfilmentStatus, pagination: { limit: 50, offset: 0 } },\n apiGatewayUrl\n );\n return data.cooBrandOrders;\n },\n });\n};\n\nexport const useBrandOrderSummary = (brandId: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'brand-order-summary', brandId],\n enabled: !!brandId,\n queryFn: async () => {\n const data = await coolQuery<{ cooBrandOrderSummary: CooBrandOrderSummary }>(\n `query CooBrandOrderSummary($brandId: ID!) {\n cooBrandOrderSummary(brandId: $brandId) {\n brandId unfulfilled confirmed shipped delivered refunded total\n }\n }`,\n { brandId },\n apiGatewayUrl\n );\n return data.cooBrandOrderSummary;\n },\n });\n};\n\nexport const useBrandOrder = (brandId: string | undefined, id: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'brand-order', brandId, id],\n enabled: !!brandId && !!id,\n queryFn: async () => {\n const data = await coolQuery<{ cooBrandOrder: CooBrandOrder | null }>(\n `query CooBrandOrder($brandId: ID!, $id: ID!) { cooBrandOrder(brandId: $brandId, id: $id) { ${BRAND_ORDER_FIELDS} } }`,\n { brandId, id },\n apiGatewayUrl\n );\n return data.cooBrandOrder;\n },\n });\n};\n\nexport const useUpdateOrderFulfilment = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: async (input: CooUpdateOrderFulfilmentInput) => {\n const data = await coolQuery<{ cooUpdateOrderFulfilment: CooBrandOrder }>(\n `mutation CooUpdateOrderFulfilment($input: CooUpdateOrderFulfilmentInput!) {\n cooUpdateOrderFulfilment(input: $input) { ${BRAND_ORDER_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooUpdateOrderFulfilment;\n },\n onSuccess: (order) => {\n queryClient.setQueryData([QK, 'brand-order', order.brandId, order.id], order);\n void queryClient.invalidateQueries({ queryKey: [QK, 'brand-orders', order.brandId] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'brand-order-summary', order.brandId] });\n },\n });\n};\n\n/**\n * Refund the brand's pieces of an order (BOFF-9702). global-billing returns the money to the\n * shopper, and the creator commissions on the refunded lines are reversed. With `restock: true`\n * the refunded stock-tracked pieces go back into stock (BOFF-9901); sending it on a completed\n * refund restocks it afterwards.\n */\nexport const useRefundBrandOrder = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: async (input: CooRefundBrandOrderInput) => {\n const data = await coolQuery<{ cooRefundBrandOrder: CooBrandOrder }>(\n `mutation CooRefundBrandOrder($input: CooRefundBrandOrderInput!) {\n cooRefundBrandOrder(input: $input) { ${BRAND_ORDER_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooRefundBrandOrder;\n },\n onSuccess: (order) => {\n queryClient.setQueryData([QK, 'brand-order', order.brandId, order.id], order);\n void queryClient.invalidateQueries({ queryKey: [QK, 'brand-orders', order.brandId] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'brand-order-summary', order.brandId] });\n // A restock (BOFF-9901) changes the pieces' stock and can put a sold-out piece back on sale.\n if (order.refund?.restockStatus === 'RESTOCKED') {\n for (const styleItemId of new Set(order.items.map((item) => item.styleItemId))) {\n void queryClient.invalidateQueries({\n queryKey: [QK, 'style-item-inventory', styleItemId],\n });\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-item', styleItemId] });\n }\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-items'] });\n }\n },\n // A failed refund is recorded on the order; refetch so the page shows why.\n onError: (_error, input) => {\n void queryClient.invalidateQueries({\n queryKey: [QK, 'brand-order', input.brandId, input.orderId],\n });\n },\n });\n};\n\n/** The brand's return requests, newest first, optionally by status (BOFF-9900). */\nexport const useBrandReturnRequests = (\n brandId: string | undefined,\n status?: CooReturnRequestStatus\n) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'brand-return-requests', brandId, status ?? 'ALL'],\n enabled: !!brandId,\n queryFn: async () => {\n const data = await coolQuery<{ cooBrandReturnRequests: CooReturnRequestConnection }>(\n `query CooBrandReturnRequests($brandId: ID!, $status: CooReturnRequestStatus, $pagination: PaginationInput) {\n cooBrandReturnRequests(brandId: $brandId, status: $status, pagination: $pagination) {\n items { ${RETURN_REQUEST_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n { brandId, status, pagination: { limit: 50, offset: 0 } },\n apiGatewayUrl\n );\n return data.cooBrandReturnRequests;\n },\n });\n};\n\nconst useReturnDecisionSettled = () => {\n const queryClient = useQueryClient();\n return (brandId: string, orderId: string, order?: CooBrandOrder) => {\n if (order) queryClient.setQueryData([QK, 'brand-order', brandId, orderId], order);\n else void queryClient.invalidateQueries({ queryKey: [QK, 'brand-order', brandId, orderId] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'brand-orders', brandId] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'brand-order-summary', brandId] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'brand-return-requests', brandId] });\n };\n};\n\n/**\n * Approve a shopper's return (BOFF-9900): refunds the brand's pieces through the brand refund and\n * marks the request approved. On an error the order is refetched so a failed refund shows why.\n */\nexport const useApproveReturnRequest = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const settle = useReturnDecisionSettled();\n return useMutation({\n mutationFn: async (input: CooApproveReturnRequestInput) => {\n const data = await coolQuery<{ cooApproveReturnRequest: CooBrandOrder }>(\n `mutation CooApproveReturnRequest($input: CooApproveReturnRequestInput!) {\n cooApproveReturnRequest(input: $input) { ${BRAND_ORDER_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooApproveReturnRequest;\n },\n onSuccess: (order, input) => settle(input.brandId, input.orderId, order),\n onError: (_error, input) => settle(input.brandId, input.orderId),\n });\n};\n\n/** Decline a shopper's return with a note the shopper sees (BOFF-9900). */\nexport const useDeclineReturnRequest = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const settle = useReturnDecisionSettled();\n return useMutation({\n mutationFn: async (input: CooDeclineReturnRequestInput) => {\n const data = await coolQuery<{ cooDeclineReturnRequest: CooBrandOrder }>(\n `mutation CooDeclineReturnRequest($input: CooDeclineReturnRequestInput!) {\n cooDeclineReturnRequest(input: $input) { ${BRAND_ORDER_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooDeclineReturnRequest;\n },\n onSuccess: (order, input) => settle(input.brandId, input.orderId, order),\n });\n};\n"],"mappings":";;;;;;AA4BA,IAAM,IAAK,iBAEL,IAAqB;;;;;;;iBAOV,EAAkB;aACtB,EAAc;oBACP,EAAsB;GAG7B,KACX,GACA,MACG;CACH,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAgB;GAAS,KAAoB;GAAM;EAClE,SAAS,CAAC,CAAC;EACX,SAAS,aACM,MAAM,EACjB;;sBAEc,EAAmB;;;YAIjC;GAAE;GAAS;GAAkB,YAAY;IAAE,OAAO;IAAI,QAAQ;IAAG;GAAE,EACnE,EACD,EACW;EAEf,CAAC;GAGS,KAAwB,MAAgC;CACnE,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAuB;GAAQ;EAC9C,SAAS,CAAC,CAAC;EACX,SAAS,aACM,MAAM,EACjB,wMAKA,EAAE,YAAS,EACX,EACD,EACW;EAEf,CAAC;GAGS,KAAiB,GAA6B,MAA2B;CACpF,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAe;GAAS;GAAG;EAC1C,SAAS,CAAC,CAAC,KAAW,CAAC,CAAC;EACxB,SAAS,aACM,MAAM,EACjB,8FAA8F,EAAmB,OACjH;GAAE;GAAS;GAAI,EACf,EACD,EACW;EAEf,CAAC;GAGS,UAAiC;CAC5C,IAAM,EAAE,qBAAkB,GAAkB,EACtC,IAAc,GAAgB;AACpC,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB;sDAC8C,EAAmB;YAEjE,EAAE,UAAO,EACT,EACD,EACW;EAEd,YAAY,MAAU;AAGf,GAFL,EAAY,aAAa;IAAC;IAAI;IAAe,EAAM;IAAS,EAAM;IAAG,EAAE,EAAM,EACxE,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAgB,EAAM;IAAQ,EAAE,CAAC,EAChF,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAuB,EAAM;IAAQ,EAAE,CAAC;;EAE/F,CAAC;GASS,UAA4B;CACvC,IAAM,EAAE,qBAAkB,GAAkB,EACtC,IAAc,GAAgB;AACpC,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB;iDACyC,EAAmB;YAE5D,EAAE,UAAO,EACT,EACD,EACW;EAEd,YAAY,MAAU;AAKpB,OAJA,EAAY,aAAa;IAAC;IAAI;IAAe,EAAM;IAAS,EAAM;IAAG,EAAE,EAAM,EACxE,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAgB,EAAM;IAAQ,EAAE,CAAC,EAChF,EAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAuB,EAAM;IAAQ,EAAE,CAAC,EAExF,EAAM,QAAQ,kBAAkB,aAAa;AAC/C,SAAK,IAAM,KAAe,IAAI,IAAI,EAAM,MAAM,KAAK,MAAS,EAAK,YAAY,CAAC,CAIvE,CAHA,EAAY,kBAAkB,EACjC,UAAU;KAAC;KAAI;KAAwB;KAAY,EACpD,CAAC,EACG,EAAY,kBAAkB,EAAE,UAAU;KAAC;KAAI;KAAc;KAAY,EAAE,CAAC;AAE9E,MAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,cAAc,EAAE,CAAC;;;EAIzE,UAAU,GAAQ,MAAU;AACrB,KAAY,kBAAkB,EACjC,UAAU;IAAC;IAAI;IAAe,EAAM;IAAS,EAAM;IAAQ,EAC5D,CAAC;;EAEL,CAAC;GAIS,KACX,GACA,MACG;CACH,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAyB;GAAS,KAAU;GAAM;EACjE,SAAS,CAAC,CAAC;EACX,SAAS,aACM,MAAM,EACjB;;sBAEc,EAAsB;;;YAIpC;GAAE;GAAS;GAAQ,YAAY;IAAE,OAAO;IAAI,QAAQ;IAAG;GAAE,EACzD,EACD,EACW;EAEf,CAAC;GAGE,UAAiC;CACrC,IAAM,IAAc,GAAgB;AACpC,SAAQ,GAAiB,GAAiB,MAA0B;AAK7D,EAJD,IAAO,EAAY,aAAa;GAAC;GAAI;GAAe;GAAS;GAAQ,EAAE,EAAM,GACvE,EAAY,kBAAkB,EAAE,UAAU;GAAC;GAAI;GAAe;GAAS;GAAQ,EAAE,CAAC,EACvF,EAAY,kBAAkB,EAAE,UAAU;GAAC;GAAI;GAAgB;GAAQ,EAAE,CAAC,EAC1E,EAAY,kBAAkB,EAAE,UAAU;GAAC;GAAI;GAAuB;GAAQ,EAAE,CAAC,EACjF,EAAY,kBAAkB,EAAE,UAAU;GAAC;GAAI;GAAyB;GAAQ,EAAE,CAAC;;GAQ/E,UAAgC;CAC3C,IAAM,EAAE,qBAAkB,GAAkB,EACtC,IAAS,GAA0B;AACzC,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB;qDAC6C,EAAmB;YAEhE,EAAE,UAAO,EACT,EACD,EACW;EAEd,YAAY,GAAO,MAAU,EAAO,EAAM,SAAS,EAAM,SAAS,EAAM;EACxE,UAAU,GAAQ,MAAU,EAAO,EAAM,SAAS,EAAM,QAAQ;EACjE,CAAC;GAIS,UAAgC;CAC3C,IAAM,EAAE,qBAAkB,GAAkB,EACtC,IAAS,GAA0B;AACzC,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB;qDAC6C,EAAmB;YAEhE,EAAE,UAAO,EACT,EACD,EACW;EAEd,YAAY,GAAO,MAAU,EAAO,EAAM,SAAS,EAAM,SAAS,EAAM;EACzE,CAAC"}
|
|
1
|
+
{"version":3,"file":"useBrandOrdersApi.js","names":[],"sources":["../../../src/coolandlovely/hooks/useBrandOrdersApi.ts"],"sourcesContent":["/**\n * Brand order hooks (BOFF-9636)\n * @module coolandlovely/hooks\n *\n * React Query layer over the brand-side order fields of `wspace-coolandlovely-svc`: the paid\n * orders that contain a brand's pieces (only that brand's lines), counts per fulfilment state,\n * and the fulfilment mutation (confirm, ship with tracking, mark delivered). Also the brand's\n * refunds (BOFF-9702) and the shopper return requests it approves or declines (BOFF-9900).\n */\n\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\n\nimport { useCoolAndLovely } from '../context';\nimport type {\n CooApproveReturnRequestInput,\n CooBrandOrder,\n CooBrandOrderConnection,\n CooBrandOrderSummary,\n CooDeclineReturnRequestInput,\n CooFulfilmentStatus,\n CooRefundBrandOrderInput,\n CooReturnRequestConnection,\n CooReturnRequestStatus,\n CooUpdateOrderFulfilmentInput,\n} from '../types';\nimport { FULFILMENT_FIELDS, REFUND_FIELDS, RETURN_REQUEST_FIELDS } from './useCommerceApi';\nimport { coolQuery } from './useCoolAndLovelyApi';\n\nconst QK = 'coolandlovely';\n\nconst BRAND_ORDER_FIELDS = `\n id orderNumber status brandId currency brandSubtotal itemCount\n shippingName shippingAddress buyerNote paidAt createdAt\n items {\n id styleItemId brandId name sku image { id } size colour unitPrice quantity lineTotal\n lookId isCreatorAttributed stockTracked\n }\n fulfilment { ${FULFILMENT_FIELDS} }\n refund { ${REFUND_FIELDS} }\n returnRequest { ${RETURN_REQUEST_FIELDS} }\n`;\n\nexport const useBrandOrders = (\n brandId: string | undefined,\n fulfilmentStatus?: CooFulfilmentStatus\n) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'brand-orders', brandId, fulfilmentStatus ?? 'ALL'],\n enabled: !!brandId,\n queryFn: async () => {\n const data = await coolQuery<{ cooBrandOrders: CooBrandOrderConnection }>(\n `query CooBrandOrders($brandId: ID!, $fulfilmentStatus: CooFulfilmentStatus, $pagination: PaginationInput) {\n cooBrandOrders(brandId: $brandId, fulfilmentStatus: $fulfilmentStatus, pagination: $pagination) {\n items { ${BRAND_ORDER_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n { brandId, fulfilmentStatus, pagination: { limit: 50, offset: 0 } },\n apiGatewayUrl\n );\n return data.cooBrandOrders;\n },\n });\n};\n\nexport const useBrandOrderSummary = (brandId: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'brand-order-summary', brandId],\n enabled: !!brandId,\n queryFn: async () => {\n const data = await coolQuery<{ cooBrandOrderSummary: CooBrandOrderSummary }>(\n `query CooBrandOrderSummary($brandId: ID!) {\n cooBrandOrderSummary(brandId: $brandId) {\n brandId unfulfilled confirmed shipped delivered refunded total\n }\n }`,\n { brandId },\n apiGatewayUrl\n );\n return data.cooBrandOrderSummary;\n },\n });\n};\n\nexport const useBrandOrder = (brandId: string | undefined, id: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'brand-order', brandId, id],\n enabled: !!brandId && !!id,\n queryFn: async () => {\n const data = await coolQuery<{ cooBrandOrder: CooBrandOrder | null }>(\n `query CooBrandOrder($brandId: ID!, $id: ID!) { cooBrandOrder(brandId: $brandId, id: $id) { ${BRAND_ORDER_FIELDS} } }`,\n { brandId, id },\n apiGatewayUrl\n );\n return data.cooBrandOrder;\n },\n });\n};\n\nexport const useUpdateOrderFulfilment = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: async (input: CooUpdateOrderFulfilmentInput) => {\n const data = await coolQuery<{ cooUpdateOrderFulfilment: CooBrandOrder }>(\n `mutation CooUpdateOrderFulfilment($input: CooUpdateOrderFulfilmentInput!) {\n cooUpdateOrderFulfilment(input: $input) { ${BRAND_ORDER_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooUpdateOrderFulfilment;\n },\n onSuccess: (order) => {\n queryClient.setQueryData([QK, 'brand-order', order.brandId, order.id], order);\n void queryClient.invalidateQueries({ queryKey: [QK, 'brand-orders', order.brandId] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'brand-order-summary', order.brandId] });\n },\n });\n};\n\n/**\n * Refund the brand's pieces of an order (BOFF-9702). global-billing returns the money to the\n * shopper, and the creator commissions on the refunded lines are reversed. With `restock: true`\n * the refunded stock-tracked pieces go back into stock (BOFF-9901); sending it on a completed\n * refund restocks it afterwards.\n */\nexport const useRefundBrandOrder = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: async (input: CooRefundBrandOrderInput) => {\n const data = await coolQuery<{ cooRefundBrandOrder: CooBrandOrder }>(\n `mutation CooRefundBrandOrder($input: CooRefundBrandOrderInput!) {\n cooRefundBrandOrder(input: $input) { ${BRAND_ORDER_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooRefundBrandOrder;\n },\n onSuccess: (order) => {\n queryClient.setQueryData([QK, 'brand-order', order.brandId, order.id], order);\n void queryClient.invalidateQueries({ queryKey: [QK, 'brand-orders', order.brandId] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'brand-order-summary', order.brandId] });\n // A restock (BOFF-9901) changes the pieces' stock and can put a sold-out piece back on sale.\n if (order.refund?.restockStatus === 'RESTOCKED') {\n for (const styleItemId of new Set(order.items.map((item) => item.styleItemId))) {\n void queryClient.invalidateQueries({\n queryKey: [QK, 'style-item-inventory', styleItemId],\n });\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-item', styleItemId] });\n }\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-items'] });\n }\n },\n // A failed refund is recorded on the order; refetch so the page shows why.\n onError: (_error, input) => {\n void queryClient.invalidateQueries({\n queryKey: [QK, 'brand-order', input.brandId, input.orderId],\n });\n },\n });\n};\n\n/** The brand's return requests, newest first, optionally by status (BOFF-9900). */\nexport const useBrandReturnRequests = (\n brandId: string | undefined,\n status?: CooReturnRequestStatus\n) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'brand-return-requests', brandId, status ?? 'ALL'],\n enabled: !!brandId,\n queryFn: async () => {\n const data = await coolQuery<{ cooBrandReturnRequests: CooReturnRequestConnection }>(\n `query CooBrandReturnRequests($brandId: ID!, $status: CooReturnRequestStatus, $pagination: PaginationInput) {\n cooBrandReturnRequests(brandId: $brandId, status: $status, pagination: $pagination) {\n items { ${RETURN_REQUEST_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n { brandId, status, pagination: { limit: 50, offset: 0 } },\n apiGatewayUrl\n );\n return data.cooBrandReturnRequests;\n },\n });\n};\n\nconst useReturnDecisionSettled = () => {\n const queryClient = useQueryClient();\n return (brandId: string, orderId: string, order?: CooBrandOrder) => {\n if (order) queryClient.setQueryData([QK, 'brand-order', brandId, orderId], order);\n else void queryClient.invalidateQueries({ queryKey: [QK, 'brand-order', brandId, orderId] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'brand-orders', brandId] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'brand-order-summary', brandId] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'brand-return-requests', brandId] });\n };\n};\n\n/**\n * Approve a shopper's return (BOFF-9900): refunds the brand's pieces through the brand refund and\n * marks the request approved. On an error the order is refetched so a failed refund shows why.\n */\nexport const useApproveReturnRequest = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const settle = useReturnDecisionSettled();\n return useMutation({\n mutationFn: async (input: CooApproveReturnRequestInput) => {\n const data = await coolQuery<{ cooApproveReturnRequest: CooBrandOrder }>(\n `mutation CooApproveReturnRequest($input: CooApproveReturnRequestInput!) {\n cooApproveReturnRequest(input: $input) { ${BRAND_ORDER_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooApproveReturnRequest;\n },\n onSuccess: (order, input) => settle(input.brandId, input.orderId, order),\n onError: (_error, input) => settle(input.brandId, input.orderId),\n });\n};\n\n/** Decline a shopper's return with a note the shopper sees (BOFF-9900). */\nexport const useDeclineReturnRequest = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const settle = useReturnDecisionSettled();\n return useMutation({\n mutationFn: async (input: CooDeclineReturnRequestInput) => {\n const data = await coolQuery<{ cooDeclineReturnRequest: CooBrandOrder }>(\n `mutation CooDeclineReturnRequest($input: CooDeclineReturnRequestInput!) {\n cooDeclineReturnRequest(input: $input) { ${BRAND_ORDER_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooDeclineReturnRequest;\n },\n onSuccess: (order, input) => settle(input.brandId, input.orderId, order),\n });\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCatalogImport.js","names":[],"sources":["../../../src/coolandlovely/hooks/useCatalogImport.ts"],"sourcesContent":["/**\n * Catalog import hooks (BOFF-3384)\n * @module coolandlovely/hooks\n *\n * Brands onboard an existing catalog from Shopify, WooCommerce or BigCommerce:\n *\n * 1. `usePreviewExternalCatalog` calls `cooPreviewExternalCatalog`, which reads\n * the merchant's store with the credentials typed into the form (used for\n * that one request, never stored) and returns the catalog mapped onto\n * CoolAndLovely brand / collection / style-item shapes.\n * 2. `useImportExternalCatalog` copies each product image (and the store logo)\n * from the platform's CDN into wspace-files, then imports everything in\n * one transaction with `cooBulkImportCatalog`, so CoolAndLovely only ever\n * stores federated File ids, never third-party image URLs.\n */\n\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\n\nimport { useCoolAndLovely } from '../context';\nimport type {\n CooBulkCatalogImportResult,\n CooBulkImportCatalogInput,\n CooBulkImportCatalogItemInput,\n CooExternalCatalogItemPreview,\n CooExternalCatalogPreview,\n CooExternalCatalogSourceInput,\n} from '../types';\nimport { coolQuery } from './useCoolAndLovelyApi';\nimport { COO_FILE_FOLDERS, uploadImageToFiles } from './useFiles';\n\nconst QK = 'coolandlovely';\n\n/** Images copied in parallel; small enough to stay polite to the platform CDN. */\nconst IMAGE_CONCURRENCY = 4;\n/** Largest image copied into Files; bigger ones are imported without an image. */\nconst MAX_IMAGE_BYTES = 10 * 1024 * 1024;\n\nconst PREVIEW_FIELDS = `\n provider sourceUrl truncated warnings\n brand { name handle tagline bio websiteUrl logoUrl tags }\n collections { name description tags }\n items {\n externalId collectionName name description category sku price currency\n colours sizes materials tags imageUrl sourceUrl\n }\n`;\n\nexport const usePreviewExternalCatalog = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (source: CooExternalCatalogSourceInput) => {\n const data = await coolQuery<{ cooPreviewExternalCatalog: CooExternalCatalogPreview }>(\n `mutation CooPreviewExternalCatalog($source: CooExternalCatalogSourceInput!) {\n cooPreviewExternalCatalog(source: $source) { ${PREVIEW_FIELDS} }\n }`,\n { source },\n apiGatewayUrl\n );\n return data.cooPreviewExternalCatalog;\n },\n });\n};\n\n/** Progress of an import run, for the progress bar. */\nexport interface CatalogImportProgress {\n phase: 'images' | 'saving';\n done: number;\n total: number;\n}\n\nexport interface ImportExternalCatalogArgs {\n preview: CooExternalCatalogPreview;\n /** Brand name and handle as the merchant confirmed them. */\n brandName: string;\n brandHandle: string;\n /** Items the merchant kept (by externalId). */\n selectedIds: ReadonlySet<string>;\n copyImages: boolean;\n onProgress?: (progress: CatalogImportProgress) => void;\n}\n\nexport interface ImportExternalCatalogResult extends CooBulkCatalogImportResult {\n imagesCopied: number;\n imagesFailed: number;\n}\n\nfunction fileNameFor(url: string, fallback: string, mimeType: string): string {\n const last = new URL(url).pathname.split('/').pop() ?? '';\n if (/\\.[a-z0-9]{2,5}$/i.test(last)) return last.slice(-120);\n const extension = mimeType.split('/')[1]?.split('+')[0] ?? 'jpg';\n return `${fallback}.${extension}`;\n}\n\n/**\n * Copy one remote image into wspace-files. Returns the File id, or null when\n * the image cannot be fetched (CORS, 404, not an image, too large) — the item\n * is then imported without an image rather than failing the whole import.\n */\nasync function copyImageToFiles(\n url: string,\n name: string,\n folder: string,\n apiGatewayUrl?: string\n): Promise<string | null> {\n try {\n const response = await fetch(url, {\n mode: 'cors',\n credentials: 'omit',\n referrerPolicy: 'no-referrer',\n });\n if (!response.ok) return null;\n const blob = await response.blob();\n if (!blob.type.startsWith('image/') || blob.size === 0 || blob.size > MAX_IMAGE_BYTES)\n return null;\n const file = new File([blob], fileNameFor(url, name, blob.type), { type: blob.type });\n const uploaded = await uploadImageToFiles(file, apiGatewayUrl, folder);\n return uploaded.id;\n } catch {\n return null;\n }\n}\n\n/** Run `task` over `items` with at most `limit` in flight, preserving order. */\nasync function mapWithConcurrency<T, R>(\n items: readonly T[],\n limit: number,\n task: (item: T, index: number) => Promise<R>\n): Promise<R[]> {\n const results = new Array<R>(items.length);\n let next = 0;\n const worker = async () => {\n while (next < items.length) {\n const index = next;\n next += 1;\n results[index] = await task(items[index] as T, index);\n }\n };\n await Promise.all(Array.from({ length: Math.min(limit, items.length) }, worker));\n return results;\n}\n\nfunction toImportItem(\n item: CooExternalCatalogItemPreview,\n imageFileId: string | null\n): CooBulkImportCatalogItemInput {\n return {\n collectionName: item.collectionName ?? '',\n name: item.name,\n ...(item.description ? { description: item.description } : {}),\n category: item.category,\n ...(item.sku ? { sku: item.sku } : {}),\n ...(imageFileId ? { imageFileId } : {}),\n price: item.price,\n currency: item.currency,\n colours: item.colours,\n sizes: item.sizes,\n materials: item.materials,\n tags: item.tags,\n };\n}\n\nexport const useImportExternalCatalog = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async ({\n preview,\n brandName,\n brandHandle,\n selectedIds,\n copyImages,\n onProgress,\n }: ImportExternalCatalogArgs): Promise<ImportExternalCatalogResult> => {\n const items = preview.items.filter((item) => selectedIds.has(item.externalId));\n let imagesCopied = 0;\n let imagesFailed = 0;\n let done = 0;\n const imageJobs = copyImages ? items.filter((item) => item.imageUrl).length : 0;\n const logoJob = copyImages && preview.brand.logoUrl ? 1 : 0;\n const total = imageJobs + logoJob;\n onProgress?.({ phase: 'images', done, total });\n\n const tick = (copied: boolean) => {\n if (copied) imagesCopied += 1;\n else imagesFailed += 1;\n done += 1;\n onProgress?.({ phase: 'images', done, total });\n };\n\n let logoFileId: string | null = null;\n if (logoJob && preview.brand.logoUrl) {\n logoFileId = await copyImageToFiles(\n preview.brand.logoUrl,\n `${brandHandle}-logo`,\n COO_FILE_FOLDERS.brands,\n apiGatewayUrl\n );\n tick(Boolean(logoFileId));\n }\n\n const imageIds = await mapWithConcurrency(items, IMAGE_CONCURRENCY, async (item, index) => {\n if (!copyImages || !item.imageUrl) return null;\n const id = await copyImageToFiles(\n item.imageUrl,\n `${brandHandle}-${index + 1}`,\n COO_FILE_FOLDERS.items,\n apiGatewayUrl\n );\n tick(Boolean(id));\n return id;\n });\n\n const usedCollections = new Set(items.map((item) => item.collectionName).filter(Boolean));\n const input: CooBulkImportCatalogInput = {\n brand: {\n name: brandName,\n handle: brandHandle,\n ...(preview.brand.tagline ? { tagline: preview.brand.tagline } : {}),\n ...(preview.brand.bio ? { bio: preview.brand.bio } : {}),\n ...(preview.brand.websiteUrl ? { websiteUrl: preview.brand.websiteUrl } : {}),\n ...(logoFileId ? { logoFileId } : {}),\n tags: preview.brand.tags,\n },\n collections: preview.collections\n .filter((collection) => usedCollections.has(collection.name))\n .map((collection) => ({\n name: collection.name,\n ...(collection.description ? { description: collection.description } : {}),\n tags: collection.tags,\n })),\n items: items.map((item, index) => toImportItem(item, imageIds[index] ?? null)),\n };\n\n onProgress?.({ phase: 'saving', done, total });\n const data = await coolQuery<{ cooBulkImportCatalog: CooBulkCatalogImportResult }>(\n `mutation CooBulkImportCatalog($input: CooBulkImportCatalogInput!) {\n cooBulkImportCatalog(input: $input) {\n brand { id name handle }\n collectionsCreated\n itemsCreated\n }\n }`,\n { input },\n apiGatewayUrl\n );\n return { ...data.cooBulkImportCatalog, imagesCopied, imagesFailed };\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'brands'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'collections'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-items'] });\n },\n });\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useCatalogImport.js","names":[],"sources":["../../../src/coolandlovely/hooks/useCatalogImport.ts"],"sourcesContent":["/**\n * Catalog import hooks (BOFF-3384)\n * @module coolandlovely/hooks\n *\n * Brands onboard an existing catalog from Shopify, WooCommerce or BigCommerce:\n *\n * 1. `usePreviewExternalCatalog` calls `cooPreviewExternalCatalog`, which reads\n * the merchant's store with the credentials typed into the form (used for\n * that one request, never stored) and returns the catalog mapped onto\n * CoolAndLovely brand / collection / style-item shapes.\n * 2. `useImportExternalCatalog` copies each product image (and the store logo)\n * from the platform's CDN into wspace-files, then imports everything in\n * one transaction with `cooBulkImportCatalog`, so CoolAndLovely only ever\n * stores federated File ids, never third-party image URLs.\n */\n\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\n\nimport { useCoolAndLovely } from '../context';\nimport type {\n CooBulkCatalogImportResult,\n CooBulkImportCatalogInput,\n CooBulkImportCatalogItemInput,\n CooExternalCatalogItemPreview,\n CooExternalCatalogPreview,\n CooExternalCatalogSourceInput,\n} from '../types';\nimport { coolQuery } from './useCoolAndLovelyApi';\nimport { COO_FILE_FOLDERS, uploadImageToFiles } from './useFiles';\n\nconst QK = 'coolandlovely';\n\n/** Images copied in parallel; small enough to stay polite to the platform CDN. */\nconst IMAGE_CONCURRENCY = 4;\n/** Largest image copied into Files; bigger ones are imported without an image. */\nconst MAX_IMAGE_BYTES = 10 * 1024 * 1024;\n\nconst PREVIEW_FIELDS = `\n provider sourceUrl truncated warnings\n brand { name handle tagline bio websiteUrl logoUrl tags }\n collections { name description tags }\n items {\n externalId collectionName name description category sku price currency\n colours sizes materials tags imageUrl sourceUrl\n }\n`;\n\nexport const usePreviewExternalCatalog = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async (source: CooExternalCatalogSourceInput) => {\n const data = await coolQuery<{ cooPreviewExternalCatalog: CooExternalCatalogPreview }>(\n `mutation CooPreviewExternalCatalog($source: CooExternalCatalogSourceInput!) {\n cooPreviewExternalCatalog(source: $source) { ${PREVIEW_FIELDS} }\n }`,\n { source },\n apiGatewayUrl\n );\n return data.cooPreviewExternalCatalog;\n },\n });\n};\n\n/** Progress of an import run, for the progress bar. */\nexport interface CatalogImportProgress {\n phase: 'images' | 'saving';\n done: number;\n total: number;\n}\n\nexport interface ImportExternalCatalogArgs {\n preview: CooExternalCatalogPreview;\n /** Brand name and handle as the merchant confirmed them. */\n brandName: string;\n brandHandle: string;\n /** Items the merchant kept (by externalId). */\n selectedIds: ReadonlySet<string>;\n copyImages: boolean;\n onProgress?: (progress: CatalogImportProgress) => void;\n}\n\nexport interface ImportExternalCatalogResult extends CooBulkCatalogImportResult {\n imagesCopied: number;\n imagesFailed: number;\n}\n\nfunction fileNameFor(url: string, fallback: string, mimeType: string): string {\n const last = new URL(url).pathname.split('/').pop() ?? '';\n if (/\\.[a-z0-9]{2,5}$/i.test(last)) return last.slice(-120);\n const extension = mimeType.split('/')[1]?.split('+')[0] ?? 'jpg';\n return `${fallback}.${extension}`;\n}\n\n/**\n * Copy one remote image into wspace-files. Returns the File id, or null when\n * the image cannot be fetched (CORS, 404, not an image, too large) — the item\n * is then imported without an image rather than failing the whole import.\n */\nasync function copyImageToFiles(\n url: string,\n name: string,\n folder: string,\n apiGatewayUrl?: string\n): Promise<string | null> {\n try {\n const response = await fetch(url, {\n mode: 'cors',\n credentials: 'omit',\n referrerPolicy: 'no-referrer',\n });\n if (!response.ok) return null;\n const blob = await response.blob();\n if (!blob.type.startsWith('image/') || blob.size === 0 || blob.size > MAX_IMAGE_BYTES)\n return null;\n const file = new File([blob], fileNameFor(url, name, blob.type), { type: blob.type });\n const uploaded = await uploadImageToFiles(file, apiGatewayUrl, folder);\n return uploaded.id;\n } catch {\n return null;\n }\n}\n\n/** Run `task` over `items` with at most `limit` in flight, preserving order. */\nasync function mapWithConcurrency<T, R>(\n items: readonly T[],\n limit: number,\n task: (item: T, index: number) => Promise<R>\n): Promise<R[]> {\n const results = new Array<R>(items.length);\n let next = 0;\n const worker = async () => {\n while (next < items.length) {\n const index = next;\n next += 1;\n results[index] = await task(items[index] as T, index);\n }\n };\n await Promise.all(Array.from({ length: Math.min(limit, items.length) }, worker));\n return results;\n}\n\nfunction toImportItem(\n item: CooExternalCatalogItemPreview,\n imageFileId: string | null\n): CooBulkImportCatalogItemInput {\n return {\n collectionName: item.collectionName ?? '',\n name: item.name,\n ...(item.description ? { description: item.description } : {}),\n category: item.category,\n ...(item.sku ? { sku: item.sku } : {}),\n ...(imageFileId ? { imageFileId } : {}),\n price: item.price,\n currency: item.currency,\n colours: item.colours,\n sizes: item.sizes,\n materials: item.materials,\n tags: item.tags,\n };\n}\n\nexport const useImportExternalCatalog = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async ({\n preview,\n brandName,\n brandHandle,\n selectedIds,\n copyImages,\n onProgress,\n }: ImportExternalCatalogArgs): Promise<ImportExternalCatalogResult> => {\n const items = preview.items.filter((item) => selectedIds.has(item.externalId));\n let imagesCopied = 0;\n let imagesFailed = 0;\n let done = 0;\n const imageJobs = copyImages ? items.filter((item) => item.imageUrl).length : 0;\n const logoJob = copyImages && preview.brand.logoUrl ? 1 : 0;\n const total = imageJobs + logoJob;\n onProgress?.({ phase: 'images', done, total });\n\n const tick = (copied: boolean) => {\n if (copied) imagesCopied += 1;\n else imagesFailed += 1;\n done += 1;\n onProgress?.({ phase: 'images', done, total });\n };\n\n let logoFileId: string | null = null;\n if (logoJob && preview.brand.logoUrl) {\n logoFileId = await copyImageToFiles(\n preview.brand.logoUrl,\n `${brandHandle}-logo`,\n COO_FILE_FOLDERS.brands,\n apiGatewayUrl\n );\n tick(Boolean(logoFileId));\n }\n\n const imageIds = await mapWithConcurrency(items, IMAGE_CONCURRENCY, async (item, index) => {\n if (!copyImages || !item.imageUrl) return null;\n const id = await copyImageToFiles(\n item.imageUrl,\n `${brandHandle}-${index + 1}`,\n COO_FILE_FOLDERS.items,\n apiGatewayUrl\n );\n tick(Boolean(id));\n return id;\n });\n\n const usedCollections = new Set(items.map((item) => item.collectionName).filter(Boolean));\n const input: CooBulkImportCatalogInput = {\n brand: {\n name: brandName,\n handle: brandHandle,\n ...(preview.brand.tagline ? { tagline: preview.brand.tagline } : {}),\n ...(preview.brand.bio ? { bio: preview.brand.bio } : {}),\n ...(preview.brand.websiteUrl ? { websiteUrl: preview.brand.websiteUrl } : {}),\n ...(logoFileId ? { logoFileId } : {}),\n tags: preview.brand.tags,\n },\n collections: preview.collections\n .filter((collection) => usedCollections.has(collection.name))\n .map((collection) => ({\n name: collection.name,\n ...(collection.description ? { description: collection.description } : {}),\n tags: collection.tags,\n })),\n items: items.map((item, index) => toImportItem(item, imageIds[index] ?? null)),\n };\n\n onProgress?.({ phase: 'saving', done, total });\n const data = await coolQuery<{ cooBulkImportCatalog: CooBulkCatalogImportResult }>(\n `mutation CooBulkImportCatalog($input: CooBulkImportCatalogInput!) {\n cooBulkImportCatalog(input: $input) {\n brand { id name handle }\n collectionsCreated\n itemsCreated\n }\n }`,\n { input },\n apiGatewayUrl\n );\n return { ...data.cooBulkImportCatalog, imagesCopied, imagesFailed };\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'brands'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'collections'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'style-items'] });\n },\n });\n};\n"],"mappings":"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"}
|
|
@@ -25,7 +25,7 @@ export interface EntityCommentsResult {
|
|
|
25
25
|
comments: EntityCommentView[];
|
|
26
26
|
}
|
|
27
27
|
/** List reviews/comments for a (entityType, entityId), newest first. */
|
|
28
|
-
export declare const useEntityComments: (entityType: string, entityId: string | undefined) => import('@tanstack/react-query').UseQueryResult<
|
|
28
|
+
export declare const useEntityComments: (entityType: string, entityId: string | undefined) => import('@tanstack/react-query').UseQueryResult<EntityCommentsResult, Error>;
|
|
29
29
|
/** Post a review/comment on a (entityType, entityId). */
|
|
30
30
|
export declare const useAddComment: () => import('@tanstack/react-query').UseMutationResult<{
|
|
31
31
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useComments.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/hooks/useComments.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAUH,+EAA+E;AAC/E,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;CACjB;AA2DD,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED,wEAAwE;AACxE,eAAO,MAAM,iBAAiB,GAAI,YAAY,MAAM,EAAE,UAAU,MAAM,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"useComments.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/hooks/useComments.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAUH,+EAA+E;AAC/E,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;CACjB;AA2DD,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED,wEAAwE;AACxE,eAAO,MAAM,iBAAiB,GAAI,YAAY,MAAM,EAAE,UAAU,MAAM,GAAG,SAAS,gFAmCjF,CAAC;AAEF,yDAAyD;AACzD,eAAO,MAAM,aAAa;QAayC,MAAM;;gBAJvD,MAAM;cACR,MAAM;UACV,MAAM;WAqBjB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useComments.js","names":[],"sources":["../../../src/coolandlovely/hooks/useComments.ts"],"sourcesContent":["/**\n * Comments hooks — reviews / feedback via wspace-conversations-svc (NO new table).\n * @module coolandlovely/hooks\n *\n * CoolAndLovely does NOT own a comment/review table. Reviews & feedback on a\n * look or brand are polymorphic `EntityComment` records owned by\n * wspace-conversations-svc, keyed by (entityType, entityId). Same graphqlFetch\n * transport (workspace gateway + workspace token) as every other coo* call.\n *\n * Commenter display names must be resolved via fe-libs useActorProfiles\n * (GLOBAL gateway) — the federated wspace `User` here exposes only ids, so\n * NEVER select firstName/name on the comment author.\n */\n\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport { clearGraphqlFetchResponseCache } from '@burdenoff/fe-libs/shared/graphql/fetch';\n\nimport { useCoolAndLovely } from '../context';\n\nconst QK = 'coolandlovely-comments';\n\n/** A single review/comment as surfaced in the MFE (scalar-only projection). */\nexport interface EntityCommentView {\n id: string;\n authorId: string;\n authorType: string;\n text: string;\n createdAt: string;\n edited: boolean;\n}\n\ninterface RawEntityComment {\n id: string;\n authorId: string;\n authorType: string;\n edited: boolean;\n createdAt: string;\n content: { text?: string | null } | null;\n}\n\nconst commentFetch = async <TData>(\n query: string,\n variables: Record<string, unknown>,\n baseUrl?: string\n): Promise<TData> => {\n const response = await graphqlFetch<TData>({\n gateway: 'workspace',\n baseUrl,\n query,\n variables,\n workspaceToken: true,\n });\n if (response.errors?.length) {\n throw new Error(response.errors[0]?.message ?? 'Comments request failed');\n }\n if (!response.data) {\n throw new Error('Comments response did not include data');\n }\n if (/^\\s*mutation\\b/.test(query)) {\n clearGraphqlFetchResponseCache();\n }\n return response.data;\n};\n\nconst GET_COMMENTS = `\n query CooGetEntityComments($input: GetCommentsInput!) {\n getEntityComments(input: $input) {\n total\n items {\n id\n authorId\n authorType\n edited\n createdAt\n content { text }\n }\n }\n }\n`;\n\nconst CREATE_COMMENT = `\n mutation CooCreateEntityComment($input: CreateEntityCommentInput!) {\n createEntityComment(input: $input) {\n id\n }\n }\n`;\n\nexport interface EntityCommentsResult {\n total: number;\n comments: EntityCommentView[];\n}\n\n/** List reviews/comments for a (entityType, entityId), newest first. */\nexport const useEntityComments = (entityType: string, entityId: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, entityType, entityId],\n enabled: Boolean(entityId),\n queryFn: async (): Promise<EntityCommentsResult> => {\n const data = await commentFetch<{\n getEntityComments: { total: number; items: RawEntityComment[] };\n }>(\n GET_COMMENTS,\n {\n input: {\n entityType,\n entityId,\n take: 100,\n sortBy: 'createdAt',\n sortOrder: 'desc',\n },\n },\n apiGatewayUrl\n );\n const conn = data.getEntityComments;\n return {\n total: conn.total,\n comments: conn.items.map((c) => ({\n id: c.id,\n authorId: c.authorId,\n authorType: (c.authorType ?? 'user').toLowerCase(),\n text: c.content?.text ?? '',\n createdAt: c.createdAt,\n edited: c.edited,\n })),\n };\n },\n });\n};\n\n/** Post a review/comment on a (entityType, entityId). */\nexport const useAddComment = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async ({\n entityType,\n entityId,\n text,\n }: {\n entityType: string;\n entityId: string;\n text: string;\n }) => {\n const data = await commentFetch<{ createEntityComment: { id: string } }>(\n CREATE_COMMENT,\n {\n input: {\n entityType,\n entityId,\n content: { text },\n },\n },\n apiGatewayUrl\n );\n return data.createEntityComment;\n },\n onSuccess: (_result, variables) => {\n void queryClient.invalidateQueries({\n queryKey: [QK, variables.entityType, variables.entityId],\n });\n },\n });\n};\n"],"mappings":";;;;;;AAoBA,IAAM,IAAK,0BAqBL,IAAe,OACnB,GACA,GACA,MACmB;CACnB,IAAM,IAAW,MAAM,EAAoB;EACzC,SAAS;EACT;EACA;EACA;EACA,gBAAgB;
|
|
1
|
+
{"version":3,"file":"useComments.js","names":[],"sources":["../../../src/coolandlovely/hooks/useComments.ts"],"sourcesContent":["/**\n * Comments hooks — reviews / feedback via wspace-conversations-svc (NO new table).\n * @module coolandlovely/hooks\n *\n * CoolAndLovely does NOT own a comment/review table. Reviews & feedback on a\n * look or brand are polymorphic `EntityComment` records owned by\n * wspace-conversations-svc, keyed by (entityType, entityId). Same graphqlFetch\n * transport (workspace gateway + workspace token) as every other coo* call.\n *\n * Commenter display names must be resolved via fe-libs useActorProfiles\n * (GLOBAL gateway) — the federated wspace `User` here exposes only ids, so\n * NEVER select firstName/name on the comment author.\n */\n\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport { clearGraphqlFetchResponseCache } from '@burdenoff/fe-libs/shared/graphql/fetch';\n\nimport { useCoolAndLovely } from '../context';\n\nconst QK = 'coolandlovely-comments';\n\n/** A single review/comment as surfaced in the MFE (scalar-only projection). */\nexport interface EntityCommentView {\n id: string;\n authorId: string;\n authorType: string;\n text: string;\n createdAt: string;\n edited: boolean;\n}\n\ninterface RawEntityComment {\n id: string;\n authorId: string;\n authorType: string;\n edited: boolean;\n createdAt: string;\n content: { text?: string | null } | null;\n}\n\nconst commentFetch = async <TData>(\n query: string,\n variables: Record<string, unknown>,\n baseUrl?: string\n): Promise<TData> => {\n const response = await graphqlFetch<TData>({\n gateway: 'workspace',\n baseUrl,\n query,\n variables,\n workspaceToken: true,\n });\n if (response.errors?.length) {\n throw new Error(response.errors[0]?.message ?? 'Comments request failed');\n }\n if (!response.data) {\n throw new Error('Comments response did not include data');\n }\n if (/^\\s*mutation\\b/.test(query)) {\n clearGraphqlFetchResponseCache();\n }\n return response.data;\n};\n\nconst GET_COMMENTS = `\n query CooGetEntityComments($input: GetCommentsInput!) {\n getEntityComments(input: $input) {\n total\n items {\n id\n authorId\n authorType\n edited\n createdAt\n content { text }\n }\n }\n }\n`;\n\nconst CREATE_COMMENT = `\n mutation CooCreateEntityComment($input: CreateEntityCommentInput!) {\n createEntityComment(input: $input) {\n id\n }\n }\n`;\n\nexport interface EntityCommentsResult {\n total: number;\n comments: EntityCommentView[];\n}\n\n/** List reviews/comments for a (entityType, entityId), newest first. */\nexport const useEntityComments = (entityType: string, entityId: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, entityType, entityId],\n enabled: Boolean(entityId),\n queryFn: async (): Promise<EntityCommentsResult> => {\n const data = await commentFetch<{\n getEntityComments: { total: number; items: RawEntityComment[] };\n }>(\n GET_COMMENTS,\n {\n input: {\n entityType,\n entityId,\n take: 100,\n sortBy: 'createdAt',\n sortOrder: 'desc',\n },\n },\n apiGatewayUrl\n );\n const conn = data.getEntityComments;\n return {\n total: conn.total,\n comments: conn.items.map((c) => ({\n id: c.id,\n authorId: c.authorId,\n authorType: (c.authorType ?? 'user').toLowerCase(),\n text: c.content?.text ?? '',\n createdAt: c.createdAt,\n edited: c.edited,\n })),\n };\n },\n });\n};\n\n/** Post a review/comment on a (entityType, entityId). */\nexport const useAddComment = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useCoolAndLovely();\n return useMutation({\n mutationFn: async ({\n entityType,\n entityId,\n text,\n }: {\n entityType: string;\n entityId: string;\n text: string;\n }) => {\n const data = await commentFetch<{ createEntityComment: { id: string } }>(\n CREATE_COMMENT,\n {\n input: {\n entityType,\n entityId,\n content: { text },\n },\n },\n apiGatewayUrl\n );\n return data.createEntityComment;\n },\n onSuccess: (_result, variables) => {\n void queryClient.invalidateQueries({\n queryKey: [QK, variables.entityType, variables.entityId],\n });\n },\n });\n};\n"],"mappings":";;;;;;AAoBA,IAAM,IAAK,0BAqBL,IAAe,OACnB,GACA,GACA,MACmB;CACnB,IAAM,IAAW,MAAM,EAAoB;EACzC,SAAS;EACT;EACA;EACA;EACA,gBAAgB;CAClB,CAAC;CACD,IAAI,EAAS,QAAQ,QACnB,MAAU,MAAM,EAAS,OAAO,EAAE,EAAE,WAAW,yBAAyB;CAE1E,IAAI,CAAC,EAAS,MACZ,MAAU,MAAM,wCAAwC;CAK1D,OAHI,iBAAiB,KAAK,CAAK,KAC7B,EAA+B,GAE1B,EAAS;AAClB,GAEM,IAAe,yQAgBf,IAAiB,8IAcV,KAAqB,GAAoB,MAAiC;CACrF,IAAM,EAAE,qBAAkB,EAAiB;CAC3C,OAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAY;EAAQ;EACnC,SAAS,EAAQ;EACjB,SAAS,YAA2C;GAgBlD,IAAM,KAAO,MAfM,EAGjB,GACA,EACE,OAAO;IACL;IACA;IACA,MAAM;IACN,QAAQ;IACR,WAAW;GACb,EACF,GACA,CACF,EAAA,CACkB;GAClB,OAAO;IACL,OAAO,EAAK;IACZ,UAAU,EAAK,MAAM,KAAK,OAAO;KAC/B,IAAI,EAAE;KACN,UAAU,EAAE;KACZ,aAAa,EAAE,cAAc,OAAA,CAAQ,YAAY;KACjD,MAAM,EAAE,SAAS,QAAQ;KACzB,WAAW,EAAE;KACb,QAAQ,EAAE;IACZ,EAAE;GACJ;EACF;CACF,CAAC;AACH,GAGa,UAAsB;CACjC,IAAM,IAAc,EAAe,GAC7B,EAAE,qBAAkB,EAAiB;CAC3C,OAAO,EAAY;EACjB,YAAY,OAAO,EACjB,eACA,aACA,eAiBO,MAXY,EACjB,GACA,EACE,OAAO;GACL;GACA;GACA,SAAS,EAAE,QAAK;EAClB,EACF,GACA,CACF,EAAA,CACY;EAEd,YAAY,GAAS,MAAc;GACjC,EAAiB,kBAAkB,EACjC,UAAU;IAAC;IAAI,EAAU;IAAY,EAAU;GAAQ,EACzD,CAAC;EACH;CACF,CAAC;AACH"}
|
|
@@ -6,7 +6,7 @@ export declare const FULFILMENT_FIELDS = "\n id orderId brandId brandName statu
|
|
|
6
6
|
export declare const REFUND_FIELDS = "\n id orderId brandId brandName amount currency reason status failureReason refundedAt\n restockStatus restockedQuantity restockedAt createdAt\n";
|
|
7
7
|
/** A shopper's return request (BOFF-9900): the shopper's order detail and the brand view. */
|
|
8
8
|
export declare const RETURN_REQUEST_FIELDS = "\n id orderId orderNumber brandId brandName reason status decisionNote decidedAt refundId\n createdAt updatedAt\n";
|
|
9
|
-
export declare const useMyCart: () => import('@tanstack/react-query').UseQueryResult<
|
|
9
|
+
export declare const useMyCart: () => import('@tanstack/react-query').UseQueryResult<CooCart, Error>;
|
|
10
10
|
export declare const useAddToCart: () => import('@tanstack/react-query').UseMutationResult<CooCart, Error, {
|
|
11
11
|
input: CooAddToCartInput;
|
|
12
12
|
}, unknown>;
|
|
@@ -17,8 +17,8 @@ export declare const useUpdateCartItem: () => import('@tanstack/react-query').Us
|
|
|
17
17
|
export declare const useRemoveCartItem: () => import('@tanstack/react-query').UseMutationResult<CooCart, Error, {
|
|
18
18
|
id: string;
|
|
19
19
|
}, unknown>;
|
|
20
|
-
export declare const useMyOrders: (status?: CooOrderStatus) => import('@tanstack/react-query').UseQueryResult<
|
|
21
|
-
export declare const useMyOrder: (id: string | undefined) => import('@tanstack/react-query').UseQueryResult<
|
|
20
|
+
export declare const useMyOrders: (status?: CooOrderStatus) => import('@tanstack/react-query').UseQueryResult<CooOrderConnection, Error>;
|
|
21
|
+
export declare const useMyOrder: (id: string | undefined) => import('@tanstack/react-query').UseQueryResult<CooOrder | null, Error>;
|
|
22
22
|
export declare const useCheckout: () => import('@tanstack/react-query').UseMutationResult<CooOrderCheckout, Error, CooCheckoutInput, unknown>;
|
|
23
23
|
export declare const useResumeOrderPayment: () => import('@tanstack/react-query').UseMutationResult<CooOrderCheckout, Error, string, unknown>;
|
|
24
24
|
export declare const useSyncOrderPayment: () => import('@tanstack/react-query').UseMutationResult<CooOrder, Error, string, unknown>;
|
|
@@ -27,7 +27,7 @@ export declare const useCancelOrder: () => import('@tanstack/react-query').UseMu
|
|
|
27
27
|
* A piece listed in the Burdenoff store, readable from any workspace. Only fetched once the
|
|
28
28
|
* workspace's own catalogue has no such piece (the shopper followed a store listing here).
|
|
29
29
|
*/
|
|
30
|
-
export declare const useStoreListedPiece: (id: string | undefined, enabled: boolean) => import('@tanstack/react-query').UseQueryResult<
|
|
30
|
+
export declare const useStoreListedPiece: (id: string | undefined, enabled: boolean) => import('@tanstack/react-query').UseQueryResult<CooStoreListedPiece | null, Error>;
|
|
31
31
|
/** Buy a store-listed piece directly: the order is created and its payment started. */
|
|
32
32
|
export declare const useBuyStoreListedPiece: () => import('@tanstack/react-query').UseMutationResult<CooOrderCheckout, Error, CooBuyStoreListedPieceInput, unknown>;
|
|
33
33
|
/**
|
|
@@ -35,15 +35,15 @@ export declare const useBuyStoreListedPiece: () => import('@tanstack/react-query
|
|
|
35
35
|
* approves (which refunds them) or declines; the order detail is refetched to show the request.
|
|
36
36
|
*/
|
|
37
37
|
export declare const useRequestReturn: () => import('@tanstack/react-query').UseMutationResult<CooReturnRequest, Error, CooRequestReturnInput, unknown>;
|
|
38
|
-
export declare const useMyCreatorEarnings: () => import('@tanstack/react-query').UseQueryResult<
|
|
39
|
-
export declare const useMyCreatorEarningsSummary: () => import('@tanstack/react-query').UseQueryResult<
|
|
38
|
+
export declare const useMyCreatorEarnings: () => import('@tanstack/react-query').UseQueryResult<CooCreatorEarningConnection, Error>;
|
|
39
|
+
export declare const useMyCreatorEarningsSummary: () => import('@tanstack/react-query').UseQueryResult<CooCreatorEarningsSummary, Error>;
|
|
40
40
|
export declare const useRequestCreatorPayout: () => import('@tanstack/react-query').UseMutationResult<CooCreatorPayout, Error, {
|
|
41
41
|
amount: number;
|
|
42
42
|
currency: string;
|
|
43
43
|
notes?: string | null;
|
|
44
44
|
}, unknown>;
|
|
45
45
|
/** The calling creator's collaboration fees: awaiting the brand's payment, or paid. */
|
|
46
|
-
export declare const useMyCollaborationPayouts: () => import('@tanstack/react-query').UseQueryResult<
|
|
46
|
+
export declare const useMyCollaborationPayouts: () => import('@tanstack/react-query').UseQueryResult<CooCollaborationPayoutConnection, Error>;
|
|
47
47
|
/** Start (or re-open) the brand owner's payment of a collaboration fee. */
|
|
48
48
|
export declare const usePayCollaborationFee: () => import('@tanstack/react-query').UseMutationResult<CooCollaborationPaymentCheckout, Error, string, unknown>;
|
|
49
49
|
/** Ask the backend to settle a collaboration fee against global-billing's payment record. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCommerceApi.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/hooks/useCommerceApi.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EACV,iBAAiB,EACjB,2BAA2B,EAC3B,OAAO,EACP,gBAAgB,EAChB,+BAA+B,EAC/B,sBAAsB,EACtB,gCAAgC,EAChC,2BAA2B,EAC3B,yBAAyB,EACzB,gBAAgB,EAChB,QAAQ,EACR,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,UAAU,CAAC;AAwBlB,iGAAiG;AACjG,eAAO,MAAM,iBAAiB,8IAG7B,CAAC;AAEF,iGAAiG;AACjG,eAAO,MAAM,aAAa,uJAGzB,CAAC;AAEF,6FAA6F;AAC7F,eAAO,MAAM,qBAAqB,wHAGjC,CAAC;AAoBF,eAAO,MAAM,SAAS
|
|
1
|
+
{"version":3,"file":"useCommerceApi.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/hooks/useCommerceApi.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EACV,iBAAiB,EACjB,2BAA2B,EAC3B,OAAO,EACP,gBAAgB,EAChB,+BAA+B,EAC/B,sBAAsB,EACtB,gCAAgC,EAChC,2BAA2B,EAC3B,yBAAyB,EACzB,gBAAgB,EAChB,QAAQ,EACR,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,UAAU,CAAC;AAwBlB,iGAAiG;AACjG,eAAO,MAAM,iBAAiB,8IAG7B,CAAC;AAEF,iGAAiG;AACjG,eAAO,MAAM,aAAa,uJAGzB,CAAC;AAEF,6FAA6F;AAC7F,eAAO,MAAM,qBAAqB,wHAGjC,CAAC;AAoBF,eAAO,MAAM,SAAS,sEAarB,CAAC;AAuBF,eAAO,MAAM,YAAY;WACE,iBAAiB;WAGzC,CAAC;AAEJ,eAAO,MAAM,iBAAiB;QACN,MAAM;cAAY,MAAM;WAK7C,CAAC;AAEJ,eAAO,MAAM,iBAAiB;QACN,MAAM;WAG3B,CAAC;AAMJ,eAAO,MAAM,WAAW,GAAI,SAAS,cAAc,8EAkBlD,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,IAAI,MAAM,GAAG,SAAS,2EAchD,CAAC;AAWF,eAAO,MAAM,WAAW,6GAcvB,CAAC;AAEF,eAAO,MAAM,qBAAqB,mGAcjC,CAAC;AAEF,eAAO,MAAM,mBAAmB,2FAc/B,CAAC;AAEF,eAAO,MAAM,cAAc,2FAc1B,CAAC;AAYF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,IAAI,MAAM,GAAG,SAAS,EAAE,SAAS,OAAO,sFAc3E,CAAC;AAEF,uFAAuF;AACvF,eAAO,MAAM,sBAAsB,wHAgBlC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,kHAkB5B,CAAC;AAMF,eAAO,MAAM,oBAAoB,0FAqBhC,CAAC;AAEF,eAAO,MAAM,2BAA2B,wFAkBvC,CAAC;AAEF,eAAO,MAAM,uBAAuB;YAII,MAAM;cAAY,MAAM;YAAU,MAAM,GAAG,IAAI;WActF,CAAC;AAWF,uFAAuF;AACvF,eAAO,MAAM,yBAAyB,+FAkBrC,CAAC;AAWF,2EAA2E;AAC3E,eAAO,MAAM,sBAAsB,kHAgBlC,CAAC;AAEF,6FAA6F;AAC7F,eAAO,MAAM,2BAA2B,yGAgBvC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCommerceApi.js","names":[],"sources":["../../../src/coolandlovely/hooks/useCommerceApi.ts"],"sourcesContent":["/**\n * Commerce API hooks (BOFF-3370)\n * @module coolandlovely/hooks\n *\n * React Query layer over the self-scoped commerce fields of `wspace-coolandlovely-svc`:\n * the shopper's cart, checkout and orders, and the creator's look commissions + payouts.\n * The client never decides that an order is paid — it opens the provider's checkout that\n * global-billing prepared and then asks the backend to settle against billing's record.\n */\n\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\n\nimport { useCoolAndLovely } from '../context';\nimport type {\n CooAddToCartInput,\n CooBuyStoreListedPieceInput,\n CooCart,\n CooCheckoutInput,\n CooCollaborationPaymentCheckout,\n CooCollaborationPayout,\n CooCollaborationPayoutConnection,\n CooCreatorEarningConnection,\n CooCreatorEarningsSummary,\n CooCreatorPayout,\n CooOrder,\n CooOrderCheckout,\n CooOrderConnection,\n CooOrderStatus,\n CooRequestReturnInput,\n CooReturnRequest,\n CooStoreListedPiece,\n} from '../types';\nimport { COLLABORATION_PAYOUT_FIELDS, coolQuery } from './useCoolAndLovelyApi';\n\nconst QK = 'coolandlovely';\n\nconst CART_FIELDS = `\n items {\n id styleItemId quantity size colour lookId unitPrice currency lineTotal isPurchasable\n availableQuantity\n styleItem { id name status image { id } brand { id name } }\n }\n itemCount subtotal currency canCheckout blockedReason\n`;\n\nconst ORDER_FIELDS = `\n id orderNumber status currency subtotal taxAmount total itemCount\n shippingName shippingAddress buyerNote paymentProvider paidAt cancelledAt refundedAmount refundedAt\n createdAt updatedAt\n items {\n id styleItemId brandId name sku image { id } size colour unitPrice quantity lineTotal\n lookId isCreatorAttributed\n }\n`;\n\n/** Per-brand fulfilment (BOFF-9636): shared by the shopper's order detail and the brand view. */\nexport const FULFILMENT_FIELDS = `\n id orderId brandId brandName status refunded carrier trackingNumber trackingUrl note\n confirmedAt shippedAt deliveredAt updatedAt\n`;\n\n/** A brand's refund of its pieces (BOFF-9702): the shopper's order detail and the brand view. */\nexport const REFUND_FIELDS = `\n id orderId brandId brandName amount currency reason status failureReason refundedAt\n restockStatus restockedQuantity restockedAt createdAt\n`;\n\n/** A shopper's return request (BOFF-9900): the shopper's order detail and the brand view. */\nexport const RETURN_REQUEST_FIELDS = `\n id orderId orderNumber brandId brandName reason status decisionNote decidedAt refundId\n createdAt updatedAt\n`;\n\nconst ORDER_DETAIL_FIELDS = `\n ${ORDER_FIELDS}\n fulfilmentStatus\n fulfilments { ${FULFILMENT_FIELDS} }\n refunds { ${REFUND_FIELDS} }\n returnRequests { ${RETURN_REQUEST_FIELDS} }\n returnWindowEndsAt\n`;\n\nconst CHECKOUT_FIELDS = `\n order { ${ORDER_FIELDS} }\n provider providerOrderId razorpayKeyId clientSecret stripePublishableKey subtotal taxAmount total currency\n`;\n\n// ---------------------------------------------------------------------------\n// Cart\n// ---------------------------------------------------------------------------\n\nexport const useMyCart = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'cart'],\n queryFn: async () => {\n const data = await coolQuery<{ cooMyCart: CooCart }>(\n `query CooMyCart { cooMyCart { ${CART_FIELDS} } }`,\n {},\n apiGatewayUrl\n );\n return data.cooMyCart;\n },\n });\n};\n\n/** Every cart mutation answers with the fresh cart, which is written straight into the cache. */\nconst useCartMutation = <TVars>(document: string, field: string) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: async (variables: TVars) => {\n const data = await coolQuery<Record<string, CooCart>>(\n document,\n variables as Record<string, unknown>,\n apiGatewayUrl\n );\n const cart = data[field];\n if (!cart) throw new Error('The cart could not be updated');\n return cart;\n },\n onSuccess: (cart) => {\n queryClient.setQueryData([QK, 'cart'], cart);\n },\n });\n};\n\nexport const useAddToCart = () =>\n useCartMutation<{ input: CooAddToCartInput }>(\n `mutation CooAddToCart($input: CooAddToCartInput!) { cooAddToCart(input: $input) { ${CART_FIELDS} } }`,\n 'cooAddToCart'\n );\n\nexport const useUpdateCartItem = () =>\n useCartMutation<{ id: string; quantity: number }>(\n `mutation CooUpdateCartItem($id: ID!, $quantity: Int!) {\n cooUpdateCartItem(id: $id, quantity: $quantity) { ${CART_FIELDS} }\n }`,\n 'cooUpdateCartItem'\n );\n\nexport const useRemoveCartItem = () =>\n useCartMutation<{ id: string }>(\n `mutation CooRemoveCartItem($id: ID!) { cooRemoveCartItem(id: $id) { ${CART_FIELDS} } }`,\n 'cooRemoveCartItem'\n );\n\n// ---------------------------------------------------------------------------\n// Orders + checkout\n// ---------------------------------------------------------------------------\n\nexport const useMyOrders = (status?: CooOrderStatus) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'orders', status ?? 'ALL'],\n queryFn: async () => {\n const data = await coolQuery<{ cooMyOrders: CooOrderConnection }>(\n `query CooMyOrders($status: CooOrderStatus, $pagination: PaginationInput) {\n cooMyOrders(status: $status, pagination: $pagination) {\n items { ${ORDER_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n { status, pagination: { limit: 50, offset: 0 } },\n apiGatewayUrl\n );\n return data.cooMyOrders;\n },\n });\n};\n\nexport const useMyOrder = (id: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'order', id],\n enabled: !!id,\n queryFn: async () => {\n const data = await coolQuery<{ cooMyOrder: CooOrder | null }>(\n `query CooMyOrder($id: ID!) { cooMyOrder(id: $id) { ${ORDER_DETAIL_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooMyOrder;\n },\n });\n};\n\nconst useOrderInvalidation = () => {\n const queryClient = useQueryClient();\n return (order: CooOrder) => {\n queryClient.setQueryData([QK, 'order', order.id], order);\n void queryClient.invalidateQueries({ queryKey: [QK, 'orders'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'cart'] });\n };\n};\n\nexport const useCheckout = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const settle = useOrderInvalidation();\n return useMutation({\n mutationFn: async (input: CooCheckoutInput) => {\n const data = await coolQuery<{ cooCheckout: CooOrderCheckout }>(\n `mutation CooCheckout($input: CooCheckoutInput!) { cooCheckout(input: $input) { ${CHECKOUT_FIELDS} } }`,\n { input },\n apiGatewayUrl\n );\n return data.cooCheckout;\n },\n onSuccess: (checkout) => settle(checkout.order),\n });\n};\n\nexport const useResumeOrderPayment = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const settle = useOrderInvalidation();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooResumeOrderPayment: CooOrderCheckout }>(\n `mutation CooResumeOrderPayment($id: ID!) { cooResumeOrderPayment(id: $id) { ${CHECKOUT_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooResumeOrderPayment;\n },\n onSuccess: (checkout) => settle(checkout.order),\n });\n};\n\nexport const useSyncOrderPayment = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const settle = useOrderInvalidation();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooSyncOrderPayment: CooOrder }>(\n `mutation CooSyncOrderPayment($id: ID!) { cooSyncOrderPayment(id: $id) { ${ORDER_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooSyncOrderPayment;\n },\n onSuccess: settle,\n });\n};\n\nexport const useCancelOrder = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const settle = useOrderInvalidation();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooCancelOrder: CooOrder }>(\n `mutation CooCancelOrder($id: ID!) { cooCancelOrder(id: $id) { ${ORDER_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooCancelOrder;\n },\n onSuccess: settle,\n });\n};\n\n// ---------------------------------------------------------------------------\n// Burdenoff store shoppers outside the brand's workspace (BOFF-10017)\n// ---------------------------------------------------------------------------\n\nconst STORE_LISTED_PIECE_FIELDS = `\n id name description category price currency sku colours sizes materials tags\n brandName brandHandle trackInventory inStock\n variants { size colour available }\n`;\n\n/**\n * A piece listed in the Burdenoff store, readable from any workspace. Only fetched once the\n * workspace's own catalogue has no such piece (the shopper followed a store listing here).\n */\nexport const useStoreListedPiece = (id: string | undefined, enabled: boolean) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'store-listed-piece', id],\n enabled: !!id && enabled,\n queryFn: async () => {\n const data = await coolQuery<{ cooStoreListedPiece: CooStoreListedPiece | null }>(\n `query CooStoreListedPiece($id: ID!) { cooStoreListedPiece(id: $id) { ${STORE_LISTED_PIECE_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooStoreListedPiece;\n },\n });\n};\n\n/** Buy a store-listed piece directly: the order is created and its payment started. */\nexport const useBuyStoreListedPiece = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const settle = useOrderInvalidation();\n return useMutation({\n mutationFn: async (input: CooBuyStoreListedPieceInput) => {\n const data = await coolQuery<{ cooBuyStoreListedPiece: CooOrderCheckout }>(\n `mutation CooBuyStoreListedPiece($input: CooBuyStoreListedPieceInput!) {\n cooBuyStoreListedPiece(input: $input) { ${CHECKOUT_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooBuyStoreListedPiece;\n },\n onSuccess: (checkout) => settle(checkout.order),\n });\n};\n\n/**\n * Ask a brand to take back its pieces of one of the caller's paid orders (BOFF-9900). The brand\n * approves (which refunds them) or declines; the order detail is refetched to show the request.\n */\nexport const useRequestReturn = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: async (input: CooRequestReturnInput) => {\n const data = await coolQuery<{ cooRequestReturn: CooReturnRequest }>(\n `mutation CooRequestReturn($input: CooRequestReturnInput!) {\n cooRequestReturn(input: $input) { ${RETURN_REQUEST_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooRequestReturn;\n },\n onSettled: (_request, _error, input) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'order', input.orderId] });\n },\n });\n};\n\n// ---------------------------------------------------------------------------\n// Creator earnings + payouts\n// ---------------------------------------------------------------------------\n\nexport const useMyCreatorEarnings = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'creator-earnings'],\n queryFn: async () => {\n const data = await coolQuery<{ cooMyCreatorEarnings: CooCreatorEarningConnection }>(\n `query CooMyCreatorEarnings($pagination: PaginationInput) {\n cooMyCreatorEarnings(pagination: $pagination) {\n items {\n id orderId orderNumber lookId collaborationId commissionRate saleAmount amount currency\n availableAt billingSyncStatus reversalStatus reversedAt createdAt\n }\n pageInfo { cursor hasMore }\n }\n }`,\n { pagination: { limit: 50, offset: 0 } },\n apiGatewayUrl\n );\n return data.cooMyCreatorEarnings;\n },\n });\n};\n\nexport const useMyCreatorEarningsSummary = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'creator-earnings-summary'],\n queryFn: async () => {\n const data = await coolQuery<{ cooMyCreatorEarningsSummary: CooCreatorEarningsSummary }>(\n `query CooMyCreatorEarningsSummary {\n cooMyCreatorEarningsSummary {\n commissionRate holdDays currency totalLifetimeAmount availableAmount pendingAmount\n reservedAmount paidAmount pendingPayoutCount unsyncedCount billingAvailable\n }\n }`,\n {},\n apiGatewayUrl\n );\n return data.cooMyCreatorEarningsSummary;\n },\n });\n};\n\nexport const useRequestCreatorPayout = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: async (input: { amount: number; currency: string; notes?: string | null }) => {\n const data = await coolQuery<{ cooRequestCreatorPayout: CooCreatorPayout }>(\n `mutation CooRequestCreatorPayout($input: CooRequestCreatorPayoutInput!) {\n cooRequestCreatorPayout(input: $input) { id status requestedAmount currency createdAt }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooRequestCreatorPayout;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'creator-earnings-summary'] });\n },\n });\n};\n\n// ---------------------------------------------------------------------------\n// Collaboration fees (BOFF-9637)\n// ---------------------------------------------------------------------------\n\nconst COLLABORATION_PAYMENT_FIELDS = `\n payout { ${COLLABORATION_PAYOUT_FIELDS} }\n provider providerOrderId razorpayKeyId clientSecret stripePublishableKey subtotal taxAmount total currency\n`;\n\n/** The calling creator's collaboration fees: awaiting the brand's payment, or paid. */\nexport const useMyCollaborationPayouts = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'collaboration-payouts'],\n queryFn: async () => {\n const data = await coolQuery<{ cooMyCollaborationPayouts: CooCollaborationPayoutConnection }>(\n `query CooMyCollaborationPayouts($pagination: PaginationInput) {\n cooMyCollaborationPayouts(pagination: $pagination) {\n items { ${COLLABORATION_PAYOUT_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n { pagination: { limit: 50, offset: 0 } },\n apiGatewayUrl\n );\n return data.cooMyCollaborationPayouts;\n },\n });\n};\n\nconst useCollaborationPayoutInvalidation = () => {\n const queryClient = useQueryClient();\n return (collaborationId: string) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'collaboration', collaborationId] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'collaboration-payouts'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'creator-earnings-summary'] });\n };\n};\n\n/** Start (or re-open) the brand owner's payment of a collaboration fee. */\nexport const usePayCollaborationFee = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const refresh = useCollaborationPayoutInvalidation();\n return useMutation({\n mutationFn: async (collaborationId: string) => {\n const data = await coolQuery<{ cooPayCollaborationFee: CooCollaborationPaymentCheckout }>(\n `mutation CooPayCollaborationFee($id: ID!) {\n cooPayCollaborationFee(id: $id) { ${COLLABORATION_PAYMENT_FIELDS} }\n }`,\n { id: collaborationId },\n apiGatewayUrl\n );\n return data.cooPayCollaborationFee;\n },\n onSuccess: (checkout) => refresh(checkout.payout.collaborationId),\n });\n};\n\n/** Ask the backend to settle a collaboration fee against global-billing's payment record. */\nexport const useSyncCollaborationPayment = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const refresh = useCollaborationPayoutInvalidation();\n return useMutation({\n mutationFn: async (collaborationId: string) => {\n const data = await coolQuery<{ cooSyncCollaborationPayment: CooCollaborationPayout }>(\n `mutation CooSyncCollaborationPayment($id: ID!) {\n cooSyncCollaborationPayment(id: $id) { ${COLLABORATION_PAYOUT_FIELDS} }\n }`,\n { id: collaborationId },\n apiGatewayUrl\n );\n return data.cooSyncCollaborationPayment;\n },\n onSuccess: (payout) => refresh(payout.collaborationId),\n });\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useCommerceApi.js","names":[],"sources":["../../../src/coolandlovely/hooks/useCommerceApi.ts"],"sourcesContent":["/**\n * Commerce API hooks (BOFF-3370)\n * @module coolandlovely/hooks\n *\n * React Query layer over the self-scoped commerce fields of `wspace-coolandlovely-svc`:\n * the shopper's cart, checkout and orders, and the creator's look commissions + payouts.\n * The client never decides that an order is paid — it opens the provider's checkout that\n * global-billing prepared and then asks the backend to settle against billing's record.\n */\n\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\n\nimport { useCoolAndLovely } from '../context';\nimport type {\n CooAddToCartInput,\n CooBuyStoreListedPieceInput,\n CooCart,\n CooCheckoutInput,\n CooCollaborationPaymentCheckout,\n CooCollaborationPayout,\n CooCollaborationPayoutConnection,\n CooCreatorEarningConnection,\n CooCreatorEarningsSummary,\n CooCreatorPayout,\n CooOrder,\n CooOrderCheckout,\n CooOrderConnection,\n CooOrderStatus,\n CooRequestReturnInput,\n CooReturnRequest,\n CooStoreListedPiece,\n} from '../types';\nimport { COLLABORATION_PAYOUT_FIELDS, coolQuery } from './useCoolAndLovelyApi';\n\nconst QK = 'coolandlovely';\n\nconst CART_FIELDS = `\n items {\n id styleItemId quantity size colour lookId unitPrice currency lineTotal isPurchasable\n availableQuantity\n styleItem { id name status image { id } brand { id name } }\n }\n itemCount subtotal currency canCheckout blockedReason\n`;\n\nconst ORDER_FIELDS = `\n id orderNumber status currency subtotal taxAmount total itemCount\n shippingName shippingAddress buyerNote paymentProvider paidAt cancelledAt refundedAmount refundedAt\n createdAt updatedAt\n items {\n id styleItemId brandId name sku image { id } size colour unitPrice quantity lineTotal\n lookId isCreatorAttributed\n }\n`;\n\n/** Per-brand fulfilment (BOFF-9636): shared by the shopper's order detail and the brand view. */\nexport const FULFILMENT_FIELDS = `\n id orderId brandId brandName status refunded carrier trackingNumber trackingUrl note\n confirmedAt shippedAt deliveredAt updatedAt\n`;\n\n/** A brand's refund of its pieces (BOFF-9702): the shopper's order detail and the brand view. */\nexport const REFUND_FIELDS = `\n id orderId brandId brandName amount currency reason status failureReason refundedAt\n restockStatus restockedQuantity restockedAt createdAt\n`;\n\n/** A shopper's return request (BOFF-9900): the shopper's order detail and the brand view. */\nexport const RETURN_REQUEST_FIELDS = `\n id orderId orderNumber brandId brandName reason status decisionNote decidedAt refundId\n createdAt updatedAt\n`;\n\nconst ORDER_DETAIL_FIELDS = `\n ${ORDER_FIELDS}\n fulfilmentStatus\n fulfilments { ${FULFILMENT_FIELDS} }\n refunds { ${REFUND_FIELDS} }\n returnRequests { ${RETURN_REQUEST_FIELDS} }\n returnWindowEndsAt\n`;\n\nconst CHECKOUT_FIELDS = `\n order { ${ORDER_FIELDS} }\n provider providerOrderId razorpayKeyId clientSecret stripePublishableKey subtotal taxAmount total currency\n`;\n\n// ---------------------------------------------------------------------------\n// Cart\n// ---------------------------------------------------------------------------\n\nexport const useMyCart = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'cart'],\n queryFn: async () => {\n const data = await coolQuery<{ cooMyCart: CooCart }>(\n `query CooMyCart { cooMyCart { ${CART_FIELDS} } }`,\n {},\n apiGatewayUrl\n );\n return data.cooMyCart;\n },\n });\n};\n\n/** Every cart mutation answers with the fresh cart, which is written straight into the cache. */\nconst useCartMutation = <TVars>(document: string, field: string) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: async (variables: TVars) => {\n const data = await coolQuery<Record<string, CooCart>>(\n document,\n variables as Record<string, unknown>,\n apiGatewayUrl\n );\n const cart = data[field];\n if (!cart) throw new Error('The cart could not be updated');\n return cart;\n },\n onSuccess: (cart) => {\n queryClient.setQueryData([QK, 'cart'], cart);\n },\n });\n};\n\nexport const useAddToCart = () =>\n useCartMutation<{ input: CooAddToCartInput }>(\n `mutation CooAddToCart($input: CooAddToCartInput!) { cooAddToCart(input: $input) { ${CART_FIELDS} } }`,\n 'cooAddToCart'\n );\n\nexport const useUpdateCartItem = () =>\n useCartMutation<{ id: string; quantity: number }>(\n `mutation CooUpdateCartItem($id: ID!, $quantity: Int!) {\n cooUpdateCartItem(id: $id, quantity: $quantity) { ${CART_FIELDS} }\n }`,\n 'cooUpdateCartItem'\n );\n\nexport const useRemoveCartItem = () =>\n useCartMutation<{ id: string }>(\n `mutation CooRemoveCartItem($id: ID!) { cooRemoveCartItem(id: $id) { ${CART_FIELDS} } }`,\n 'cooRemoveCartItem'\n );\n\n// ---------------------------------------------------------------------------\n// Orders + checkout\n// ---------------------------------------------------------------------------\n\nexport const useMyOrders = (status?: CooOrderStatus) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'orders', status ?? 'ALL'],\n queryFn: async () => {\n const data = await coolQuery<{ cooMyOrders: CooOrderConnection }>(\n `query CooMyOrders($status: CooOrderStatus, $pagination: PaginationInput) {\n cooMyOrders(status: $status, pagination: $pagination) {\n items { ${ORDER_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n { status, pagination: { limit: 50, offset: 0 } },\n apiGatewayUrl\n );\n return data.cooMyOrders;\n },\n });\n};\n\nexport const useMyOrder = (id: string | undefined) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'order', id],\n enabled: !!id,\n queryFn: async () => {\n const data = await coolQuery<{ cooMyOrder: CooOrder | null }>(\n `query CooMyOrder($id: ID!) { cooMyOrder(id: $id) { ${ORDER_DETAIL_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooMyOrder;\n },\n });\n};\n\nconst useOrderInvalidation = () => {\n const queryClient = useQueryClient();\n return (order: CooOrder) => {\n queryClient.setQueryData([QK, 'order', order.id], order);\n void queryClient.invalidateQueries({ queryKey: [QK, 'orders'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'cart'] });\n };\n};\n\nexport const useCheckout = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const settle = useOrderInvalidation();\n return useMutation({\n mutationFn: async (input: CooCheckoutInput) => {\n const data = await coolQuery<{ cooCheckout: CooOrderCheckout }>(\n `mutation CooCheckout($input: CooCheckoutInput!) { cooCheckout(input: $input) { ${CHECKOUT_FIELDS} } }`,\n { input },\n apiGatewayUrl\n );\n return data.cooCheckout;\n },\n onSuccess: (checkout) => settle(checkout.order),\n });\n};\n\nexport const useResumeOrderPayment = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const settle = useOrderInvalidation();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooResumeOrderPayment: CooOrderCheckout }>(\n `mutation CooResumeOrderPayment($id: ID!) { cooResumeOrderPayment(id: $id) { ${CHECKOUT_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooResumeOrderPayment;\n },\n onSuccess: (checkout) => settle(checkout.order),\n });\n};\n\nexport const useSyncOrderPayment = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const settle = useOrderInvalidation();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooSyncOrderPayment: CooOrder }>(\n `mutation CooSyncOrderPayment($id: ID!) { cooSyncOrderPayment(id: $id) { ${ORDER_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooSyncOrderPayment;\n },\n onSuccess: settle,\n });\n};\n\nexport const useCancelOrder = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const settle = useOrderInvalidation();\n return useMutation({\n mutationFn: async (id: string) => {\n const data = await coolQuery<{ cooCancelOrder: CooOrder }>(\n `mutation CooCancelOrder($id: ID!) { cooCancelOrder(id: $id) { ${ORDER_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooCancelOrder;\n },\n onSuccess: settle,\n });\n};\n\n// ---------------------------------------------------------------------------\n// Burdenoff store shoppers outside the brand's workspace (BOFF-10017)\n// ---------------------------------------------------------------------------\n\nconst STORE_LISTED_PIECE_FIELDS = `\n id name description category price currency sku colours sizes materials tags\n brandName brandHandle trackInventory inStock\n variants { size colour available }\n`;\n\n/**\n * A piece listed in the Burdenoff store, readable from any workspace. Only fetched once the\n * workspace's own catalogue has no such piece (the shopper followed a store listing here).\n */\nexport const useStoreListedPiece = (id: string | undefined, enabled: boolean) => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'store-listed-piece', id],\n enabled: !!id && enabled,\n queryFn: async () => {\n const data = await coolQuery<{ cooStoreListedPiece: CooStoreListedPiece | null }>(\n `query CooStoreListedPiece($id: ID!) { cooStoreListedPiece(id: $id) { ${STORE_LISTED_PIECE_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return data.cooStoreListedPiece;\n },\n });\n};\n\n/** Buy a store-listed piece directly: the order is created and its payment started. */\nexport const useBuyStoreListedPiece = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const settle = useOrderInvalidation();\n return useMutation({\n mutationFn: async (input: CooBuyStoreListedPieceInput) => {\n const data = await coolQuery<{ cooBuyStoreListedPiece: CooOrderCheckout }>(\n `mutation CooBuyStoreListedPiece($input: CooBuyStoreListedPieceInput!) {\n cooBuyStoreListedPiece(input: $input) { ${CHECKOUT_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooBuyStoreListedPiece;\n },\n onSuccess: (checkout) => settle(checkout.order),\n });\n};\n\n/**\n * Ask a brand to take back its pieces of one of the caller's paid orders (BOFF-9900). The brand\n * approves (which refunds them) or declines; the order detail is refetched to show the request.\n */\nexport const useRequestReturn = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: async (input: CooRequestReturnInput) => {\n const data = await coolQuery<{ cooRequestReturn: CooReturnRequest }>(\n `mutation CooRequestReturn($input: CooRequestReturnInput!) {\n cooRequestReturn(input: $input) { ${RETURN_REQUEST_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooRequestReturn;\n },\n onSettled: (_request, _error, input) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'order', input.orderId] });\n },\n });\n};\n\n// ---------------------------------------------------------------------------\n// Creator earnings + payouts\n// ---------------------------------------------------------------------------\n\nexport const useMyCreatorEarnings = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'creator-earnings'],\n queryFn: async () => {\n const data = await coolQuery<{ cooMyCreatorEarnings: CooCreatorEarningConnection }>(\n `query CooMyCreatorEarnings($pagination: PaginationInput) {\n cooMyCreatorEarnings(pagination: $pagination) {\n items {\n id orderId orderNumber lookId collaborationId commissionRate saleAmount amount currency\n availableAt billingSyncStatus reversalStatus reversedAt createdAt\n }\n pageInfo { cursor hasMore }\n }\n }`,\n { pagination: { limit: 50, offset: 0 } },\n apiGatewayUrl\n );\n return data.cooMyCreatorEarnings;\n },\n });\n};\n\nexport const useMyCreatorEarningsSummary = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'creator-earnings-summary'],\n queryFn: async () => {\n const data = await coolQuery<{ cooMyCreatorEarningsSummary: CooCreatorEarningsSummary }>(\n `query CooMyCreatorEarningsSummary {\n cooMyCreatorEarningsSummary {\n commissionRate holdDays currency totalLifetimeAmount availableAmount pendingAmount\n reservedAmount paidAmount pendingPayoutCount unsyncedCount billingAvailable\n }\n }`,\n {},\n apiGatewayUrl\n );\n return data.cooMyCreatorEarningsSummary;\n },\n });\n};\n\nexport const useRequestCreatorPayout = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: async (input: { amount: number; currency: string; notes?: string | null }) => {\n const data = await coolQuery<{ cooRequestCreatorPayout: CooCreatorPayout }>(\n `mutation CooRequestCreatorPayout($input: CooRequestCreatorPayoutInput!) {\n cooRequestCreatorPayout(input: $input) { id status requestedAmount currency createdAt }\n }`,\n { input },\n apiGatewayUrl\n );\n return data.cooRequestCreatorPayout;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'creator-earnings-summary'] });\n },\n });\n};\n\n// ---------------------------------------------------------------------------\n// Collaboration fees (BOFF-9637)\n// ---------------------------------------------------------------------------\n\nconst COLLABORATION_PAYMENT_FIELDS = `\n payout { ${COLLABORATION_PAYOUT_FIELDS} }\n provider providerOrderId razorpayKeyId clientSecret stripePublishableKey subtotal taxAmount total currency\n`;\n\n/** The calling creator's collaboration fees: awaiting the brand's payment, or paid. */\nexport const useMyCollaborationPayouts = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, 'collaboration-payouts'],\n queryFn: async () => {\n const data = await coolQuery<{ cooMyCollaborationPayouts: CooCollaborationPayoutConnection }>(\n `query CooMyCollaborationPayouts($pagination: PaginationInput) {\n cooMyCollaborationPayouts(pagination: $pagination) {\n items { ${COLLABORATION_PAYOUT_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n { pagination: { limit: 50, offset: 0 } },\n apiGatewayUrl\n );\n return data.cooMyCollaborationPayouts;\n },\n });\n};\n\nconst useCollaborationPayoutInvalidation = () => {\n const queryClient = useQueryClient();\n return (collaborationId: string) => {\n void queryClient.invalidateQueries({ queryKey: [QK, 'collaboration', collaborationId] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'collaboration-payouts'] });\n void queryClient.invalidateQueries({ queryKey: [QK, 'creator-earnings-summary'] });\n };\n};\n\n/** Start (or re-open) the brand owner's payment of a collaboration fee. */\nexport const usePayCollaborationFee = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const refresh = useCollaborationPayoutInvalidation();\n return useMutation({\n mutationFn: async (collaborationId: string) => {\n const data = await coolQuery<{ cooPayCollaborationFee: CooCollaborationPaymentCheckout }>(\n `mutation CooPayCollaborationFee($id: ID!) {\n cooPayCollaborationFee(id: $id) { ${COLLABORATION_PAYMENT_FIELDS} }\n }`,\n { id: collaborationId },\n apiGatewayUrl\n );\n return data.cooPayCollaborationFee;\n },\n onSuccess: (checkout) => refresh(checkout.payout.collaborationId),\n });\n};\n\n/** Ask the backend to settle a collaboration fee against global-billing's payment record. */\nexport const useSyncCollaborationPayment = () => {\n const { apiGatewayUrl } = useCoolAndLovely();\n const refresh = useCollaborationPayoutInvalidation();\n return useMutation({\n mutationFn: async (collaborationId: string) => {\n const data = await coolQuery<{ cooSyncCollaborationPayment: CooCollaborationPayout }>(\n `mutation CooSyncCollaborationPayment($id: ID!) {\n cooSyncCollaborationPayment(id: $id) { ${COLLABORATION_PAYOUT_FIELDS} }\n }`,\n { id: collaborationId },\n apiGatewayUrl\n );\n return data.cooSyncCollaborationPayment;\n },\n onSuccess: (payout) => refresh(payout.collaborationId),\n });\n};\n"],"mappings":"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"}
|