@burdenoff/microfe-coolandlovely 2026.1028.4 → 2026.1030.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/hooks/useCommerceApi.d.ts +8 -1
- package/dist/coolandlovely/hooks/useCommerceApi.d.ts.map +1 -1
- package/dist/coolandlovely/hooks/useCommerceApi.js +32 -13
- package/dist/coolandlovely/hooks/useCommerceApi.js.map +1 -1
- package/dist/coolandlovely/pages/items/StoreListedPieceView.d.ts +11 -0
- package/dist/coolandlovely/pages/items/StoreListedPieceView.d.ts.map +1 -0
- package/dist/coolandlovely/pages/items/StoreListedPieceView.js +352 -0
- package/dist/coolandlovely/pages/items/StoreListedPieceView.js.map +1 -0
- package/dist/coolandlovely/pages/items/StyleItemDetailPage.d.ts +4 -0
- package/dist/coolandlovely/pages/items/StyleItemDetailPage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/items/StyleItemDetailPage.js +116 -111
- package/dist/coolandlovely/pages/items/StyleItemDetailPage.js.map +1 -1
- package/dist/coolandlovely/types/commerce.d.ts +38 -1
- package/dist/coolandlovely/types/commerce.d.ts.map +1 -1
- package/dist/services/createSandboxAssistantTransport.d.ts.map +1 -1
- package/dist/services/createSandboxAssistantTransport.js +9 -5
- package/dist/services/createSandboxAssistantTransport.js.map +1 -1
- package/package.json +3 -3
|
@@ -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,
|
|
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
|
-
},
|
|
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
|
-
},
|
|
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
|
-
},
|
|
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
|
-
},
|
|
157
|
+
}, N = `
|
|
139
158
|
payout { ${t} }
|
|
140
159
|
provider providerOrderId razorpayKeyId clientSecret stripePublishableKey subtotal taxAmount total currency
|
|
141
|
-
`,
|
|
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
|
-
},
|
|
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
|
-
},
|
|
165
|
-
let { apiGatewayUrl: t } = e(), i =
|
|
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) { ${
|
|
187
|
+
cooPayCollaborationFee(id: $id) { ${N} }
|
|
169
188
|
}`, { id: e }, t)).cooPayCollaborationFee,
|
|
170
189
|
onSuccess: (e) => i(e.payout.collaborationId)
|
|
171
190
|
});
|
|
172
|
-
},
|
|
173
|
-
let { apiGatewayUrl: i } = e(), a =
|
|
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,
|
|
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":";;;;;AAgCA,IAAM,IAAK,iBAEL,IAAc,kQASd,IAAe,oVAWR,IAAoB,6IAMpB,IAAgB,sJAMhB,IAAwB,uHAK/B,IAAsB;IACxB,EAAa;;kBAEC,EAAkB;cACtB,EAAc;qBACP,EAAsB;;GAIrC,IAAkB;YACZ,EAAa;;GAQZ,UAAkB;CAC7B,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU,CAAC,GAAI,OAAO;EACtB,SAAS,aACM,MAAM,EACjB,iCAAiC,EAAY,OAC7C,EAAE,EACF,EACD,EACW;EAEf,CAAC;GAIE,KAA0B,GAAkB,MAAkB;CAClE,IAAM,EAAE,qBAAkB,GAAkB,EACtC,IAAc,GAAgB;AACpC,QAAO,EAAY;EACjB,YAAY,OAAO,MAAqB;GAMtC,IAAM,KALO,MAAM,EACjB,GACA,GACA,EACD,EACiB;AAClB,OAAI,CAAC,EAAM,OAAU,MAAM,gCAAgC;AAC3D,UAAO;;EAET,YAAY,MAAS;AACnB,KAAY,aAAa,CAAC,GAAI,OAAO,EAAE,EAAK;;EAE/C,CAAC;GAGS,UACX,EACE,qFAAqF,EAAY,OACjG,eACD,EAEU,UACX,EACE;0DACsD,EAAY;QAElE,oBACD,EAEU,UACX,EACE,uEAAuE,EAAY,OACnF,oBACD,EAMU,KAAe,MAA4B;CACtD,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAU,KAAU;GAAM;EACzC,SAAS,aACM,MAAM,EACjB;;sBAEc,EAAa;;;YAI3B;GAAE;GAAQ,YAAY;IAAE,OAAO;IAAI,QAAQ;IAAG;GAAE,EAChD,EACD,EACW;EAEf,CAAC;GAGS,KAAc,MAA2B;CACpD,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAS;GAAG;EAC3B,SAAS,CAAC,CAAC;EACX,SAAS,aACM,MAAM,EACjB,sDAAsD,EAAoB,OAC1E,EAAE,OAAI,EACN,EACD,EACW;EAEf,CAAC;GAGE,UAA6B;CACjC,IAAM,IAAc,GAAgB;AACpC,SAAQ,MAAoB;AAGrB,EAFL,EAAY,aAAa;GAAC;GAAI;GAAS,EAAM;GAAG,EAAE,EAAM,EACnD,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,SAAS,EAAE,CAAC,EAC3D,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,OAAO,EAAE,CAAC;;GAIrD,UAAoB;CAC/B,IAAM,EAAE,qBAAkB,GAAkB,EACtC,IAAS,GAAsB;AACrC,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB,kFAAkF,EAAgB,OAClG,EAAE,UAAO,EACT,EACD,EACW;EAEd,YAAY,MAAa,EAAO,EAAS,MAAM;EAChD,CAAC;GAGS,UAA8B;CACzC,IAAM,EAAE,qBAAkB,GAAkB,EACtC,IAAS,GAAsB;AACrC,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB,+EAA+E,EAAgB,OAC/F,EAAE,OAAI,EACN,EACD,EACW;EAEd,YAAY,MAAa,EAAO,EAAS,MAAM;EAChD,CAAC;GAGS,UAA4B;CACvC,IAAM,EAAE,qBAAkB,GAAkB;AAE5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB,2EAA2E,EAAa,OACxF,EAAE,OAAI,EACN,EACD,EACW;EAEd,WAVa,GAAsB;EAWpC,CAAC;GAGS,UAAuB;CAClC,IAAM,EAAE,qBAAkB,GAAkB;AAE5C,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB,iEAAiE,EAAa,OAC9E,EAAE,OAAI,EACN,EACD,EACW;EAEd,WAVa,GAAsB;EAWpC,CAAC;GAOS,UAAyB;CACpC,IAAM,EAAE,qBAAkB,GAAkB,EACtC,IAAc,GAAgB;AACpC,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB;8CACsC,EAAsB;YAE5D,EAAE,UAAO,EACT,EACD,EACW;EAEd,YAAY,GAAU,GAAQ,MAAU;AACjC,KAAY,kBAAkB,EAAE,UAAU;IAAC;IAAI;IAAS,EAAM;IAAQ,EAAE,CAAC;;EAEjF,CAAC;GAOS,UAA6B;CACxC,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU,CAAC,GAAI,mBAAmB;EAClC,SAAS,aACM,MAAM,EACjB,sZASA,EAAE,YAAY;GAAE,OAAO;GAAI,QAAQ;GAAG,EAAE,EACxC,EACD,EACW;EAEf,CAAC;GAGS,UAAoC;CAC/C,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU,CAAC,GAAI,2BAA2B;EAC1C,SAAS,aACM,MAAM,EACjB,iSAMA,EAAE,EACF,EACD,EACW;EAEf,CAAC;GAGS,UAAgC;CAC3C,IAAM,EAAE,qBAAkB,GAAkB,EACtC,IAAc,GAAgB;AACpC,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB,2LAGA,EAAE,UAAO,EACT,EACD,EACW;EAEd,iBAAiB;AACV,KAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,2BAA2B,EAAE,CAAC;;EAErF,CAAC;GAOE,IAA+B;aACxB,EAA4B;;GAK5B,UAAkC;CAC7C,IAAM,EAAE,qBAAkB,GAAkB;AAC5C,QAAO,EAAS;EACd,UAAU,CAAC,GAAI,wBAAwB;EACvC,SAAS,aACM,MAAM,EACjB;;sBAEc,EAA4B;;;YAI1C,EAAE,YAAY;GAAE,OAAO;GAAI,QAAQ;GAAG,EAAE,EACxC,EACD,EACW;EAEf,CAAC;GAGE,UAA2C;CAC/C,IAAM,IAAc,GAAgB;AACpC,SAAQ,MAA4B;AAG7B,EAFA,EAAY,kBAAkB,EAAE,UAAU;GAAC;GAAI;GAAiB;GAAgB,EAAE,CAAC,EACnF,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,wBAAwB,EAAE,CAAC,EAC1E,EAAY,kBAAkB,EAAE,UAAU,CAAC,GAAI,2BAA2B,EAAE,CAAC;;GAKzE,UAA+B;CAC1C,IAAM,EAAE,qBAAkB,GAAkB,EACtC,IAAU,GAAoC;AACpD,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB;8CACsC,EAA6B;YAEnE,EAAE,IAAI,GAAiB,EACvB,EACD,EACW;EAEd,YAAY,MAAa,EAAQ,EAAS,OAAO,gBAAgB;EAClE,CAAC;GAIS,UAAoC;CAC/C,IAAM,EAAE,qBAAkB,GAAkB,EACtC,IAAU,GAAoC;AACpD,QAAO,EAAY;EACjB,YAAY,OAAO,OACJ,MAAM,EACjB;mDAC2C,EAA4B;YAEvE,EAAE,IAAI,GAAiB,EACvB,EACD,EACW;EAEd,YAAY,MAAW,EAAQ,EAAO,gBAAgB;EACvD,CAAC"}
|
|
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
|