@burdenoff/microfe-coolandlovely 2026.1028.4 → 2026.1029.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.
@@ -1,4 +1,4 @@
1
- import { CooAddToCartInput, CooCart, CooCheckoutInput, CooCollaborationPaymentCheckout, CooCollaborationPayout, CooCollaborationPayoutConnection, CooCreatorEarningConnection, CooCreatorEarningsSummary, CooCreatorPayout, CooOrder, CooOrderCheckout, CooOrderConnection, CooOrderStatus, CooRequestReturnInput, CooReturnRequest } from '../types';
1
+ import { CooAddToCartInput, CooBuyStoreListedPieceInput, CooCart, CooCheckoutInput, CooCollaborationPaymentCheckout, CooCollaborationPayout, CooCollaborationPayoutConnection, CooCreatorEarningConnection, CooCreatorEarningsSummary, CooCreatorPayout, CooOrder, CooOrderCheckout, CooOrderConnection, CooOrderStatus, CooRequestReturnInput, CooReturnRequest, CooStoreListedPiece } from '../types';
2
2
 
3
3
  /** Per-brand fulfilment (BOFF-9636): shared by the shopper's order detail and the brand view. */
4
4
  export declare const FULFILMENT_FIELDS = "\n id orderId brandId brandName status refunded carrier trackingNumber trackingUrl note\n confirmedAt shippedAt deliveredAt updatedAt\n";
@@ -23,6 +23,13 @@ export declare const useCheckout: () => import('@tanstack/react-query').UseMutat
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>;
25
25
  export declare const useCancelOrder: () => import('@tanstack/react-query').UseMutationResult<CooOrder, Error, string, unknown>;
26
+ /**
27
+ * A piece listed in the Burdenoff store, readable from any workspace. Only fetched once the
28
+ * workspace's own catalogue has no such piece (the shopper followed a store listing here).
29
+ */
30
+ export declare const useStoreListedPiece: (id: string | undefined, enabled: boolean) => import('@tanstack/react-query').UseQueryResult<NoInfer<CooStoreListedPiece | null>, Error>;
31
+ /** Buy a store-listed piece directly: the order is created and its payment started. */
32
+ export declare const useBuyStoreListedPiece: () => import('@tanstack/react-query').UseMutationResult<CooOrderCheckout, Error, CooBuyStoreListedPieceInput, unknown>;
26
33
  /**
27
34
  * Ask a brand to take back its pieces of one of the caller's paid orders (BOFF-9900). The brand
28
35
  * approves (which refunds them) or declines; the order detail is refetched to show the request.
@@ -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,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,EACjB,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,+EAarB,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,uFAkBlD,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,IAAI,MAAM,GAAG,SAAS,oFAchD,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;AAEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,kHAkB5B,CAAC;AAMF,eAAO,MAAM,oBAAoB,mGAqBhC,CAAC;AAEF,eAAO,MAAM,2BAA2B,iGAkBvC,CAAC;AAEF,eAAO,MAAM,uBAAuB;YAII,MAAM;cAAY,MAAM;YAAU,MAAM,GAAG,IAAI;WActF,CAAC;AAWF,uFAAuF;AACvF,eAAO,MAAM,yBAAyB,wGAkBrC,CAAC;AAWF,2EAA2E;AAC3E,eAAO,MAAM,sBAAsB,kHAgBlC,CAAC;AAEF,6FAA6F;AAC7F,eAAO,MAAM,2BAA2B,yGAgBvC,CAAC"}
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,+EAarB,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,uFAkBlD,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,IAAI,MAAM,GAAG,SAAS,oFAchD,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,+FAc3E,CAAC;AAEF,uFAAuF;AACvF,eAAO,MAAM,sBAAsB,wHAgBlC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,kHAkB5B,CAAC;AAMF,eAAO,MAAM,oBAAoB,mGAqBhC,CAAC;AAEF,eAAO,MAAM,2BAA2B,iGAkBvC,CAAC;AAEF,eAAO,MAAM,uBAAuB;YAII,MAAM;cAAY,MAAM;YAAU,MAAM,GAAG,IAAI;WActF,CAAC;AAWF,uFAAuF;AACvF,eAAO,MAAM,yBAAyB,wGAkBrC,CAAC;AAWF,2EAA2E;AAC3E,eAAO,MAAM,sBAAsB,kHAgBlC,CAAC;AAEF,6FAA6F;AAC7F,eAAO,MAAM,2BAA2B,yGAgBvC,CAAC"}
@@ -98,7 +98,26 @@ var o = "coolandlovely", s = "\n items {\n id styleItemId quantity size colo
98
98
  mutationFn: async (e) => (await n(`mutation CooCancelOrder($id: ID!) { cooCancelOrder(id: $id) { ${c} } }`, { id: e }, t)).cooCancelOrder,
99
99
  onSuccess: x()
100
100
  });
101
- }, E = () => {
101
+ }, E = "\n id name description category price currency sku colours sizes materials tags\n brandName brandHandle trackInventory inStock\n variants { size colour available }\n", D = (t, r) => {
102
+ let { apiGatewayUrl: a } = e();
103
+ return i({
104
+ queryKey: [
105
+ o,
106
+ "store-listed-piece",
107
+ t
108
+ ],
109
+ enabled: !!t && r,
110
+ queryFn: async () => (await n(`query CooStoreListedPiece($id: ID!) { cooStoreListedPiece(id: $id) { ${E} } }`, { id: t }, a)).cooStoreListedPiece
111
+ });
112
+ }, O = () => {
113
+ let { apiGatewayUrl: t } = e(), i = x();
114
+ return r({
115
+ mutationFn: async (e) => (await n(`mutation CooBuyStoreListedPiece($input: CooBuyStoreListedPieceInput!) {
116
+ cooBuyStoreListedPiece(input: $input) { ${p} }
117
+ }`, { input: e }, t)).cooBuyStoreListedPiece,
118
+ onSuccess: (e) => i(e.order)
119
+ });
120
+ }, k = () => {
102
121
  let { apiGatewayUrl: t } = e(), i = a();
103
122
  return r({
104
123
  mutationFn: async (e) => (await n(`mutation CooRequestReturn($input: CooRequestReturnInput!) {
@@ -112,7 +131,7 @@ var o = "coolandlovely", s = "\n items {\n id styleItemId quantity size colo
112
131
  ] });
113
132
  }
114
133
  });
115
- }, D = () => {
134
+ }, A = () => {
116
135
  let { apiGatewayUrl: t } = e();
117
136
  return i({
118
137
  queryKey: [o, "creator-earnings"],
@@ -121,13 +140,13 @@ var o = "coolandlovely", s = "\n items {\n id styleItemId quantity size colo
121
140
  offset: 0
122
141
  } }, t)).cooMyCreatorEarnings
123
142
  });
124
- }, O = () => {
143
+ }, j = () => {
125
144
  let { apiGatewayUrl: t } = e();
126
145
  return i({
127
146
  queryKey: [o, "creator-earnings-summary"],
128
147
  queryFn: async () => (await n("query CooMyCreatorEarningsSummary {\n cooMyCreatorEarningsSummary {\n commissionRate holdDays currency totalLifetimeAmount availableAmount pendingAmount\n reservedAmount paidAmount pendingPayoutCount unsyncedCount billingAvailable\n }\n }", {}, t)).cooMyCreatorEarningsSummary
129
148
  });
130
- }, k = () => {
149
+ }, M = () => {
131
150
  let { apiGatewayUrl: t } = e(), i = a();
132
151
  return r({
133
152
  mutationFn: async (e) => (await n("mutation CooRequestCreatorPayout($input: CooRequestCreatorPayoutInput!) {\n cooRequestCreatorPayout(input: $input) { id status requestedAmount currency createdAt }\n }", { input: e }, t)).cooRequestCreatorPayout,
@@ -135,10 +154,10 @@ var o = "coolandlovely", s = "\n items {\n id styleItemId quantity size colo
135
154
  i.invalidateQueries({ queryKey: [o, "creator-earnings-summary"] });
136
155
  }
137
156
  });
138
- }, A = `
157
+ }, N = `
139
158
  payout { ${t} }
140
159
  provider providerOrderId razorpayKeyId clientSecret stripePublishableKey subtotal taxAmount total currency
141
- `, j = () => {
160
+ `, P = () => {
142
161
  let { apiGatewayUrl: r } = e();
143
162
  return i({
144
163
  queryKey: [o, "collaboration-payouts"],
@@ -152,7 +171,7 @@ var o = "coolandlovely", s = "\n items {\n id styleItemId quantity size colo
152
171
  offset: 0
153
172
  } }, r)).cooMyCollaborationPayouts
154
173
  });
155
- }, M = () => {
174
+ }, F = () => {
156
175
  let e = a();
157
176
  return (t) => {
158
177
  e.invalidateQueries({ queryKey: [
@@ -161,16 +180,16 @@ var o = "coolandlovely", s = "\n items {\n id styleItemId quantity size colo
161
180
  t
162
181
  ] }), e.invalidateQueries({ queryKey: [o, "collaboration-payouts"] }), e.invalidateQueries({ queryKey: [o, "creator-earnings-summary"] });
163
182
  };
164
- }, N = () => {
165
- let { apiGatewayUrl: t } = e(), i = M();
183
+ }, I = () => {
184
+ let { apiGatewayUrl: t } = e(), i = F();
166
185
  return r({
167
186
  mutationFn: async (e) => (await n(`mutation CooPayCollaborationFee($id: ID!) {
168
- cooPayCollaborationFee(id: $id) { ${A} }
187
+ cooPayCollaborationFee(id: $id) { ${N} }
169
188
  }`, { id: e }, t)).cooPayCollaborationFee,
170
189
  onSuccess: (e) => i(e.payout.collaborationId)
171
190
  });
172
- }, P = () => {
173
- let { apiGatewayUrl: i } = e(), a = M();
191
+ }, L = () => {
192
+ let { apiGatewayUrl: i } = e(), a = F();
174
193
  return r({
175
194
  mutationFn: async (e) => (await n(`mutation CooSyncCollaborationPayment($id: ID!) {
176
195
  cooSyncCollaborationPayment(id: $id) { ${t} }
@@ -179,6 +198,6 @@ var o = "coolandlovely", s = "\n items {\n id styleItemId quantity size colo
179
198
  });
180
199
  };
181
200
  //#endregion
182
- export { l as FULFILMENT_FIELDS, u as REFUND_FIELDS, d as RETURN_REQUEST_FIELDS, g as useAddToCart, T as useCancelOrder, S as useCheckout, m as useMyCart, j as useMyCollaborationPayouts, D as useMyCreatorEarnings, O as useMyCreatorEarningsSummary, b as useMyOrder, y as useMyOrders, N as usePayCollaborationFee, v as useRemoveCartItem, k as useRequestCreatorPayout, E as useRequestReturn, C as useResumeOrderPayment, P as useSyncCollaborationPayment, w as useSyncOrderPayment, _ as useUpdateCartItem };
201
+ export { l as FULFILMENT_FIELDS, u as REFUND_FIELDS, d as RETURN_REQUEST_FIELDS, g as useAddToCart, O as useBuyStoreListedPiece, T as useCancelOrder, S as useCheckout, m as useMyCart, P as useMyCollaborationPayouts, A as useMyCreatorEarnings, j as useMyCreatorEarningsSummary, b as useMyOrder, y as useMyOrders, I as usePayCollaborationFee, v as useRemoveCartItem, M as useRequestCreatorPayout, k as useRequestReturn, C as useResumeOrderPayment, D as useStoreListedPiece, L as useSyncCollaborationPayment, w as useSyncOrderPayment, _ as useUpdateCartItem };
183
202
 
184
203
  //# sourceMappingURL=useCommerceApi.js.map
@@ -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 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} 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 * 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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"}
@@ -0,0 +1,11 @@
1
+ import { FC } from 'react';
2
+
3
+ /**
4
+ * The fallback piece page for a store shopper. Renders "Item not found" when the store does not
5
+ * list the piece either (drafts, retired pieces, pieces of unpublished brands).
6
+ */
7
+ export declare const StoreListedPieceView: FC<{
8
+ itemId: string | undefined;
9
+ onRetry: () => void;
10
+ }>;
11
+ //# sourceMappingURL=StoreListedPieceView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StoreListedPieceView.d.ts","sourceRoot":"","sources":["../../../../src/coolandlovely/pages/items/StoreListedPieceView.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,EAAE,EAAY,MAAM,OAAO,CAAC;AAkS1C;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,EAAE,CAAC;IAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CAkIxF,CAAC"}
@@ -0,0 +1,352 @@
1
+ import { useCoolAndLovely as e } from "../../context/CoolAndLovelyContext.js";
2
+ import { cn as t } from "../../utils/cn.js";
3
+ import { PageLayout as n } from "../../components/PageLayout.js";
4
+ import { useTr as r } from "../../hooks/useTr.js";
5
+ import "../../hooks/index.js";
6
+ import { ErrorView as i, LoadingView as a } from "../../components/StateViews.js";
7
+ import { Thumbnail as o } from "../../components/Thumbnail.js";
8
+ import { formatPrice as s, titleCase as c } from "../../utils/formatters.js";
9
+ import { categoryIcon as l } from "../../utils/icons.js";
10
+ import { TextAreaField as u, TextField as d } from "../../components/Field.js";
11
+ import { TagList as f } from "../../components/TagList.js";
12
+ import { ColourSwatchRow as p } from "../../components/ColourSwatchRow.js";
13
+ import { useBuyStoreListedPiece as m, useStoreListedPiece as h, useSyncOrderPayment as g } from "../../hooks/useCommerceApi.js";
14
+ import { PayForOrder as _ } from "../../components/PayForOrder.js";
15
+ import { useState as v } from "react";
16
+ import { ArrowLeft as y, Loader2 as b, ShoppingBag as x, Store as S } from "lucide-react";
17
+ import { jsx as C, jsxs as w } from "react/jsx-runtime";
18
+ import { GlassCard as T } from "@burdenoff/fe-libs/ui";
19
+ //#region src/coolandlovely/pages/items/StoreListedPieceView.tsx
20
+ var E = 10, D = 5, O = (e) => t("inline-flex min-w-9 items-center justify-center rounded-full border px-3 py-1 text-sm font-medium transition-colors disabled:opacity-40 disabled:line-through", e ? "border-action-primary-bg bg-action-primary-bg text-action-primary-text" : "border-border-seam text-text-primary hover:bg-bg-sunken"), k = "inline-flex w-full items-center justify-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2.5 text-sm font-semibold text-action-primary-text transition-colors hover:bg-action-primary-bg/90 disabled:opacity-50";
21
+ function A(e, t, n) {
22
+ return e.trackInventory ? e.variants.filter((e) => (t === null || (e.size ?? "") === t) && (n === null || (e.colour ?? "") === n)).reduce((e, t) => e + t.available, 0) : null;
23
+ }
24
+ var j = ({ piece: e, onCheckout: n }) => {
25
+ let i = r(), a = m(), [o, c] = v(e.sizes.length === 1 ? e.sizes[0] ?? null : null), [l, f] = v(e.colours.length === 1 ? e.colours[0] ?? null : null), [p, h] = v(1), [g, _] = v(""), [y, S] = v(""), [T, j] = v("");
26
+ if (!e.inStock) return /* @__PURE__ */ C("p", {
27
+ className: "rounded-lg border border-border-seam bg-bg-sunken p-3 text-sm text-text-secondary",
28
+ children: i("coolandlovely.storePiece.soldOut", "This piece is sold out right now.")
29
+ });
30
+ let M = e.sizes.length > 0 && !o, N = e.colours.length > 0 && !l, P = M || N ? null : A(e, o ?? "", l ?? ""), F = P !== null && P <= 0, I = P === null ? E : Math.max(1, Math.min(E, P)), L = !M && !N && !F && g.trim() !== "" && y.trim() !== "";
31
+ return /* @__PURE__ */ w("div", {
32
+ className: "space-y-4",
33
+ "data-testid": "store-buy-panel",
34
+ children: [
35
+ e.sizes.length > 0 && /* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("p", {
36
+ className: "mb-2 text-xs font-medium uppercase tracking-wide text-text-secondary",
37
+ children: i("coolandlovely.cart.chooseSize", "Choose a size")
38
+ }), /* @__PURE__ */ C("div", {
39
+ className: "flex flex-wrap gap-2",
40
+ children: e.sizes.map((t) => /* @__PURE__ */ C("button", {
41
+ type: "button",
42
+ "aria-pressed": o === t,
43
+ disabled: A(e, t, l) === 0,
44
+ onClick: () => {
45
+ c(t), h(1);
46
+ },
47
+ className: O(o === t),
48
+ children: t
49
+ }, t))
50
+ })] }),
51
+ e.colours.length > 0 && /* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("p", {
52
+ className: "mb-2 text-xs font-medium uppercase tracking-wide text-text-secondary",
53
+ children: i("coolandlovely.cart.chooseColour", "Choose a colour")
54
+ }), /* @__PURE__ */ C("div", {
55
+ className: "flex flex-wrap gap-2",
56
+ children: e.colours.map((t) => /* @__PURE__ */ C("button", {
57
+ type: "button",
58
+ "aria-pressed": l === t,
59
+ disabled: A(e, o, t) === 0,
60
+ onClick: () => {
61
+ f(t), h(1);
62
+ },
63
+ className: O(l === t),
64
+ children: t
65
+ }, t))
66
+ })] }),
67
+ /* @__PURE__ */ w("div", {
68
+ className: "flex items-center gap-3",
69
+ children: [/* @__PURE__ */ C("label", {
70
+ htmlFor: "coo-store-quantity",
71
+ className: "text-sm text-text-secondary",
72
+ children: i("coolandlovely.cart.quantity", "Quantity")
73
+ }), /* @__PURE__ */ C("select", {
74
+ id: "coo-store-quantity",
75
+ value: p,
76
+ onChange: (e) => h(Number(e.target.value)),
77
+ className: "rounded-lg border border-border-seam bg-bg-surface px-2 py-1.5 text-sm text-text-primary",
78
+ children: Array.from({ length: I }, (e, t) => t + 1).map((e) => /* @__PURE__ */ C("option", {
79
+ value: e,
80
+ children: e
81
+ }, e))
82
+ })]
83
+ }),
84
+ P !== null && /* @__PURE__ */ C("p", {
85
+ "data-testid": "store-stock-left",
86
+ className: t("text-sm font-medium", F || P <= D ? "text-status-warning-text" : "text-text-secondary"),
87
+ children: F ? i("coolandlovely.cart.soldOut", "Sold out in this size and colour") : P <= D ? i("coolandlovely.cart.onlyLeft", "Only {{count}} left", { count: P }) : i("coolandlovely.cart.inStock", "In stock")
88
+ }),
89
+ /* @__PURE__ */ w("div", {
90
+ className: "space-y-3 border-t border-border-seam pt-4",
91
+ children: [
92
+ /* @__PURE__ */ C(d, {
93
+ id: "coo-store-shipping-name",
94
+ label: i("coolandlovely.checkout.shippingName", "Full name"),
95
+ value: g,
96
+ onChange: _,
97
+ required: !0
98
+ }),
99
+ /* @__PURE__ */ C(u, {
100
+ id: "coo-store-shipping-address",
101
+ label: i("coolandlovely.checkout.shippingAddress", "Shipping address"),
102
+ value: y,
103
+ onChange: S,
104
+ rows: 3,
105
+ required: !0
106
+ }),
107
+ /* @__PURE__ */ C(d, {
108
+ id: "coo-store-buyer-note",
109
+ label: i("coolandlovely.checkout.note", "Note for the brand (optional)"),
110
+ value: T,
111
+ onChange: j
112
+ })
113
+ ]
114
+ }),
115
+ /* @__PURE__ */ C("p", {
116
+ className: "text-xs text-text-secondary",
117
+ children: i("coolandlovely.cart.taxNote", "Tax is calculated when you place the order.")
118
+ }),
119
+ a.error && /* @__PURE__ */ C("p", {
120
+ className: "text-sm text-status-error-text",
121
+ children: a.error.message
122
+ }),
123
+ /* @__PURE__ */ w("button", {
124
+ type: "button",
125
+ disabled: !L || a.isPending,
126
+ onClick: () => {
127
+ a.mutate({
128
+ styleItemId: e.id,
129
+ quantity: p,
130
+ size: o,
131
+ colour: l,
132
+ shippingName: g.trim(),
133
+ shippingAddress: y.trim(),
134
+ buyerNote: T.trim() || null
135
+ }, { onSuccess: n });
136
+ },
137
+ className: k,
138
+ children: [a.isPending ? /* @__PURE__ */ C(b, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ C(x, { className: "h-4 w-4" }), i("coolandlovely.storePiece.buyNow", "Buy now · {{amount}}", { amount: s(e.price * p, e.currency) })]
139
+ })
140
+ ]
141
+ });
142
+ }, M = ({ session: t }) => {
143
+ let i = r(), { navigateTo: a } = e(), o = g();
144
+ return /* @__PURE__ */ C(n, {
145
+ title: i("coolandlovely.checkout.payTitle", "Pay for your order"),
146
+ description: t.order.orderNumber,
147
+ children: /* @__PURE__ */ C("div", {
148
+ className: "mx-auto max-w-lg space-y-4",
149
+ children: /* @__PURE__ */ w(T, {
150
+ treatment: "glass",
151
+ className: "space-y-4 p-6",
152
+ children: [
153
+ /* @__PURE__ */ w("dl", {
154
+ className: "space-y-2 text-sm",
155
+ children: [
156
+ /* @__PURE__ */ w("div", {
157
+ className: "flex justify-between",
158
+ children: [/* @__PURE__ */ C("dt", {
159
+ className: "text-text-secondary",
160
+ children: i("coolandlovely.checkout.subtotal", "Subtotal")
161
+ }), /* @__PURE__ */ C("dd", {
162
+ className: "tabular-nums text-text-primary",
163
+ children: s(t.subtotal, t.currency)
164
+ })]
165
+ }),
166
+ /* @__PURE__ */ w("div", {
167
+ className: "flex justify-between",
168
+ children: [/* @__PURE__ */ C("dt", {
169
+ className: "text-text-secondary",
170
+ children: i("coolandlovely.checkout.tax", "Tax")
171
+ }), /* @__PURE__ */ C("dd", {
172
+ className: "tabular-nums text-text-primary",
173
+ children: s(t.taxAmount, t.currency)
174
+ })]
175
+ }),
176
+ /* @__PURE__ */ w("div", {
177
+ className: "flex justify-between border-t border-border-seam pt-2 text-base font-semibold",
178
+ children: [/* @__PURE__ */ C("dt", {
179
+ className: "text-text-primary",
180
+ children: i("coolandlovely.checkout.total", "Total")
181
+ }), /* @__PURE__ */ C("dd", {
182
+ className: "tabular-nums text-text-primary",
183
+ "data-testid": "store-checkout-total",
184
+ children: s(t.total, t.currency)
185
+ })]
186
+ })
187
+ ]
188
+ }),
189
+ /* @__PURE__ */ C(_, {
190
+ checkout: t,
191
+ onSettle: async () => {
192
+ await o.mutateAsync(t.order.id).catch(() => void 0), a(`/orders/${t.order.id}`);
193
+ }
194
+ }),
195
+ /* @__PURE__ */ C("button", {
196
+ type: "button",
197
+ onClick: () => a(`/orders/${t.order.id}`),
198
+ className: "w-full text-center text-sm font-medium text-text-secondary hover:underline",
199
+ children: i("coolandlovely.checkout.payLater", "Pay later from My Orders")
200
+ })
201
+ ]
202
+ })
203
+ })
204
+ });
205
+ }, N = ({ itemId: t, onRetry: u }) => {
206
+ let d = r(), { navigateTo: m } = e(), g = h(t, !0), [_, b] = v(null), x = d("coolandlovely.storePiece.pageTitle", "Style item");
207
+ if (_) return /* @__PURE__ */ C(M, { session: _ });
208
+ if (g.isLoading) return /* @__PURE__ */ C(n, {
209
+ title: x,
210
+ children: /* @__PURE__ */ C(a, { label: d("coolandlovely.storePiece.loading", "Loading item…") })
211
+ });
212
+ let E = g.data;
213
+ return g.isError || !E ? /* @__PURE__ */ C(n, {
214
+ title: x,
215
+ children: /* @__PURE__ */ C(i, {
216
+ title: d("coolandlovely.storePiece.notFound", "Item not found"),
217
+ onRetry: () => {
218
+ u(), g.refetch();
219
+ }
220
+ })
221
+ }) : /* @__PURE__ */ C(n, {
222
+ title: E.name,
223
+ description: E.brandName,
224
+ actions: /* @__PURE__ */ w("button", {
225
+ type: "button",
226
+ onClick: () => m("/discover"),
227
+ className: "inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken",
228
+ children: [
229
+ /* @__PURE__ */ C(y, { className: "h-4 w-4" }),
230
+ " ",
231
+ d("coolandlovely.storePiece.back", "Discover")
232
+ ]
233
+ }),
234
+ children: /* @__PURE__ */ w("div", {
235
+ className: "grid grid-cols-1 gap-6 lg:grid-cols-3",
236
+ "data-testid": "store-listed-piece",
237
+ children: [/* @__PURE__ */ C("div", {
238
+ className: "lg:col-span-2",
239
+ children: /* @__PURE__ */ w(T, {
240
+ treatment: "glass",
241
+ className: "overflow-hidden p-0",
242
+ children: [/* @__PURE__ */ C(o, {
243
+ icon: l(E.category, 48),
244
+ seed: E.id,
245
+ alt: E.name,
246
+ className: "aspect-[4/5] w-full"
247
+ }), E.description && /* @__PURE__ */ C("div", {
248
+ className: "p-6",
249
+ children: /* @__PURE__ */ C("p", {
250
+ className: "text-sm leading-relaxed text-text-secondary",
251
+ children: E.description
252
+ })
253
+ })]
254
+ })
255
+ }), /* @__PURE__ */ w("div", {
256
+ className: "space-y-4",
257
+ children: [/* @__PURE__ */ w(T, {
258
+ treatment: "glass",
259
+ className: "space-y-5 p-6",
260
+ children: [
261
+ /* @__PURE__ */ w("div", { children: [
262
+ /* @__PURE__ */ w("p", {
263
+ className: "inline-flex items-center gap-1.5 text-xs font-medium text-accent-primary",
264
+ children: [/* @__PURE__ */ C(S, { className: "h-3.5 w-3.5" }), d("coolandlovely.storePiece.fromStore", "Listed in the Burdenoff store")]
265
+ }),
266
+ /* @__PURE__ */ C("h2", {
267
+ className: "mt-2 text-2xl font-semibold leading-tight text-text-primary",
268
+ children: E.name
269
+ }),
270
+ /* @__PURE__ */ w("p", {
271
+ className: "mt-1 text-sm font-medium text-text-secondary",
272
+ children: [E.brandName, /* @__PURE__ */ w("span", {
273
+ className: "ml-1 text-text-tertiary",
274
+ children: ["@", E.brandHandle]
275
+ })]
276
+ }),
277
+ /* @__PURE__ */ w("p", {
278
+ className: "mt-3 text-3xl font-bold text-text-primary tabular-nums",
279
+ children: [s(E.price, E.currency), /* @__PURE__ */ C("span", {
280
+ className: "ml-2 text-base font-medium text-text-secondary",
281
+ children: E.currency
282
+ })]
283
+ })
284
+ ] }),
285
+ E.colours.length > 0 && /* @__PURE__ */ C(p, {
286
+ colours: E.colours,
287
+ max: 12
288
+ }),
289
+ /* @__PURE__ */ C("div", {
290
+ className: "border-t border-border-seam pt-5",
291
+ children: /* @__PURE__ */ C(j, {
292
+ piece: E,
293
+ onCheckout: b
294
+ })
295
+ }),
296
+ E.materials.length > 0 && /* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("p", {
297
+ className: "mb-1 text-xs font-medium uppercase tracking-wide text-text-secondary",
298
+ children: d("coolandlovely.storePiece.materials", "Materials")
299
+ }), /* @__PURE__ */ C("p", {
300
+ className: "text-sm text-text-primary",
301
+ children: E.materials.join(", ")
302
+ })] }),
303
+ E.tags.length > 0 && /* @__PURE__ */ C(f, {
304
+ tags: E.tags,
305
+ max: 12,
306
+ tone: "accent"
307
+ })
308
+ ]
309
+ }), /* @__PURE__ */ w(T, {
310
+ treatment: "plain",
311
+ className: "p-5",
312
+ children: [
313
+ /* @__PURE__ */ C("h3", {
314
+ className: "mb-3 text-sm font-semibold text-text-primary",
315
+ children: d("coolandlovely.storePiece.details", "Details")
316
+ }),
317
+ /* @__PURE__ */ w("dl", {
318
+ className: "space-y-2 text-sm",
319
+ children: [/* @__PURE__ */ w("div", {
320
+ className: "flex justify-between gap-2",
321
+ children: [/* @__PURE__ */ C("dt", {
322
+ className: "text-text-secondary",
323
+ children: d("coolandlovely.storePiece.category", "Category")
324
+ }), /* @__PURE__ */ C("dd", {
325
+ className: "text-text-primary",
326
+ children: c(E.category)
327
+ })]
328
+ }), /* @__PURE__ */ w("div", {
329
+ className: "flex justify-between gap-2",
330
+ children: [/* @__PURE__ */ C("dt", {
331
+ className: "text-text-secondary",
332
+ children: "SKU"
333
+ }), /* @__PURE__ */ C("dd", {
334
+ className: "text-text-primary",
335
+ children: E.sku ?? "—"
336
+ })]
337
+ })]
338
+ }),
339
+ /* @__PURE__ */ C("p", {
340
+ className: "mt-3 text-xs text-text-secondary",
341
+ children: d("coolandlovely.storePiece.soldBy", "Sold and shipped by {{brand}}. Your order appears in My Orders.", { brand: E.brandName })
342
+ })
343
+ ]
344
+ })]
345
+ })]
346
+ })
347
+ });
348
+ };
349
+ //#endregion
350
+ export { N as StoreListedPieceView };
351
+
352
+ //# sourceMappingURL=StoreListedPieceView.js.map