@riosst100/pwa-marketplace 2.4.4 → 2.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/i18n/en_US.json +509 -508
- package/i18n/id_ID.json +1 -1
- package/package.json +1 -1
- package/src/componentOverrideMapping.js +1 -0
- package/src/overwrites/peregrine/lib/talons/CartPage/PriceSummary/priceSummary.gql.js +42 -0
- package/src/overwrites/peregrine/lib/talons/CartPage/PriceSummary/usePriceSummary.js +170 -0
- package/src/overwrites/venia-ui/lib/components/Adapter/adapter.js +13 -0
- package/src/overwrites/venia-ui/lib/components/CartPage/PriceSummary/priceSummary.js +6 -75
- package/src/overwrites/venia-ui/lib/components/CartPage/PriceSummary/priceSummary.module.css +4 -2
- package/src/overwrites/venia-ui/lib/components/CartPage/ProductListing/product.js +1 -1
- package/src/overwrites/venia-ui/lib/components/CartPage/ProductListing/product.module.css +1 -1
- package/src/overwrites/venia-ui/lib/components/CartPage/ProductListing/productListing.js +45 -24
- package/src/overwrites/venia-ui/lib/components/CartPage/ProductListingBySeller/index.js +1 -0
- package/src/overwrites/venia-ui/lib/components/CartPage/ProductListingBySeller/product.js +278 -0
- package/src/overwrites/venia-ui/lib/components/CartPage/ProductListingBySeller/product.module.css +156 -0
- package/src/overwrites/venia-ui/lib/components/CartPage/ProductListingBySeller/productListingBySeller.js +125 -0
- package/src/overwrites/venia-ui/lib/components/CartPage/ProductListingBySeller/productListingBySeller.module.css +33 -0
- package/src/overwrites/venia-ui/lib/components/CartPage/cartPage.js +11 -8
- package/src/overwrites/venia-ui/lib/components/CartPage/cartPage.module.css +1 -1
- package/src/overwrites/venia-ui/lib/components/Header/cartTrigger.js +12 -11
- package/src/talons/CartPage/ProductListingBySeller/checkoutBySeller.gql.js +21 -0
- package/src/talons/CartPage/ProductListingBySeller/useProductListingBySeller.js +73 -0
package/i18n/id_ID.json
CHANGED
|
@@ -335,7 +335,7 @@
|
|
|
335
335
|
"priceAdjustments.couponCode": "Enter Coupon Code",
|
|
336
336
|
"priceAdjustments.giftOptions": "See Gift Options",
|
|
337
337
|
"priceAdjustments.shippingMethod": "Estimate your Shipping",
|
|
338
|
-
"priceSummary.checkoutButton": "
|
|
338
|
+
"priceSummary.checkoutButton": "Checkout",
|
|
339
339
|
"priceSummary.discountSummary.hideDiscounts": "Hide individual discounts.",
|
|
340
340
|
"priceSummary.discountSummary.showDiscounts": "Show individual discounts.",
|
|
341
341
|
"priceSummary.errorText": "Something went wrong. Please refresh and try again.",
|
package/package.json
CHANGED
|
@@ -28,6 +28,7 @@ module.exports = componentOverrideMapping = {
|
|
|
28
28
|
[`@magento/peregrine/lib/talons/Breadcrumbs/useBreadcrumbs.js`]: '@riosst100/pwa-marketplace/src/overwrites/peregrine/lib/talons/Breadcrumbs/useBreadcrumbs.js',
|
|
29
29
|
[`@magento/peregrine/lib/talons/FilterModal/useFilterList.js`]: '@riosst100/pwa-marketplace/src/overwrites/peregrine/lib/talons/FilterModal/useFilterList.js',
|
|
30
30
|
[`@magento/peregrine/lib/talons/FilterSidebar/useFilterSidebar.js`]: '@riosst100/pwa-marketplace/src/overwrites/peregrine/lib/talons/FilterSidebar/useFilterSidebar.js',
|
|
31
|
+
[`@magento/peregrine/lib/talons/CartPage/PriceSummary/usePriceSummary.js`]: '@riosst100/pwa-marketplace/src/overwrites/peregrine/lib/talons/CartPage/PriceSummary/usePriceSummary.js',
|
|
31
32
|
[`@magento/venia-ui/lib/components/FilterSidebar/filterSidebar.js`]: '@riosst100/pwa-marketplace/src/overwrites/venia-ui/lib/components/FilterSidebar/filterSidebar.js',
|
|
32
33
|
[`@magento/venia-ui/lib/components/TextInput/index.js`]: '@riosst100/pwa-marketplace/src/overwrites/venia-ui/lib/components/TextInput/index.js',
|
|
33
34
|
[`@magento/venia-ui/lib/components/Pagination/index.js`]: '@riosst100/pwa-marketplace/src/overwrites/venia-ui/lib/components/Pagination/index.js',
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { gql } from '@apollo/client';
|
|
2
|
+
import { PriceSummaryFragment } from '@magento/peregrine/lib/talons/CartPage/PriceSummary/priceSummaryFragments.gql';
|
|
3
|
+
|
|
4
|
+
const GET_PRICE_SUMMARY = gql`
|
|
5
|
+
query getPriceSummary($cartId: String!) {
|
|
6
|
+
cart(cart_id: $cartId) {
|
|
7
|
+
id
|
|
8
|
+
...PriceSummaryFragment
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
${PriceSummaryFragment}
|
|
12
|
+
`;
|
|
13
|
+
|
|
14
|
+
const INIT_CHECKOUT_SPLIT_CART_MUTATION = gql`
|
|
15
|
+
mutation InitCheckoutSplitCart(
|
|
16
|
+
$input: SubmitSplitCartInput!
|
|
17
|
+
) {
|
|
18
|
+
initCheckoutSplitCart(
|
|
19
|
+
input: $input
|
|
20
|
+
) {
|
|
21
|
+
id
|
|
22
|
+
parent_id
|
|
23
|
+
quote_id
|
|
24
|
+
is_active
|
|
25
|
+
is_ordered
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
`;
|
|
29
|
+
|
|
30
|
+
export const CREATE_CART = gql`
|
|
31
|
+
# This mutation will return a masked cart id. If a bearer token is provided for
|
|
32
|
+
# a logged in user it will return the cart id for that user.
|
|
33
|
+
mutation createCart {
|
|
34
|
+
cartId: createEmptyCart
|
|
35
|
+
}
|
|
36
|
+
`;
|
|
37
|
+
|
|
38
|
+
export default {
|
|
39
|
+
getPriceSummaryQuery: GET_PRICE_SUMMARY,
|
|
40
|
+
initCheckoutSplitCartMutation: INIT_CHECKOUT_SPLIT_CART_MUTATION,
|
|
41
|
+
createCartMutation: CREATE_CART
|
|
42
|
+
};
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
import { useHistory, useRouteMatch } from 'react-router-dom';
|
|
3
|
+
import { useCartContext } from '@magento/peregrine/lib/context/cart';
|
|
4
|
+
import mergeOperations from '@magento/peregrine/lib/util/shallowMerge';
|
|
5
|
+
import DEFAULT_OPERATIONS from './priceSummary.gql';
|
|
6
|
+
import {
|
|
7
|
+
useApolloClient,
|
|
8
|
+
useMutation,
|
|
9
|
+
useQuery
|
|
10
|
+
} from '@apollo/client';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @ignore
|
|
14
|
+
*
|
|
15
|
+
* Flattens query data into a simple object. We create this here rather than
|
|
16
|
+
* having each line summary line component destructure its own data because
|
|
17
|
+
* only the parent "price summary" component knows the data structure.
|
|
18
|
+
*
|
|
19
|
+
* @param {Object} data query data
|
|
20
|
+
*/
|
|
21
|
+
const flattenData = data => {
|
|
22
|
+
if (!data) return {};
|
|
23
|
+
return {
|
|
24
|
+
subtotal: data.cart.prices.subtotal_excluding_tax,
|
|
25
|
+
total: data.cart.prices.grand_total,
|
|
26
|
+
discounts: data.cart.prices.discounts,
|
|
27
|
+
giftCards: data.cart.applied_gift_cards,
|
|
28
|
+
giftOptions: data.cart.prices.gift_options,
|
|
29
|
+
taxes: data.cart.prices.applied_taxes,
|
|
30
|
+
shipping: data.cart.shipping_addresses
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* This talon contains logic for a price summary component.
|
|
36
|
+
* It performs effects and returns prop data for rendering the component.
|
|
37
|
+
*
|
|
38
|
+
* This talon performs the following effects:
|
|
39
|
+
*
|
|
40
|
+
* - Log a GraphQL error if it occurs when getting the price summary
|
|
41
|
+
*
|
|
42
|
+
* @function
|
|
43
|
+
*
|
|
44
|
+
* @param {Object} props
|
|
45
|
+
* @param {PriceSummaryQueries} props.queries GraphQL queries for a price summary component.
|
|
46
|
+
*
|
|
47
|
+
* @returns {PriceSummaryTalonProps}
|
|
48
|
+
*
|
|
49
|
+
* @example <caption>Importing into your project</caption>
|
|
50
|
+
* import { usePriceSummary } from '@magento/peregrine/lib/talons/CartPage/PriceSummary/usePriceSummary';
|
|
51
|
+
*/
|
|
52
|
+
export const usePriceSummary = (props = {}) => {
|
|
53
|
+
const operations = mergeOperations(DEFAULT_OPERATIONS, props.operations);
|
|
54
|
+
const { getPriceSummaryQuery, initCheckoutSplitCartMutation, createCartMutation } = operations;
|
|
55
|
+
|
|
56
|
+
const apolloClient = useApolloClient();
|
|
57
|
+
|
|
58
|
+
const [{ cartId }, { createSellerCart, createCart, removeCart }] = useCartContext();
|
|
59
|
+
const history = useHistory();
|
|
60
|
+
// We don't want to display "Estimated" or the "Proceed" button in checkout.
|
|
61
|
+
const match = useRouteMatch('/checkout');
|
|
62
|
+
const isCheckout = !!match;
|
|
63
|
+
|
|
64
|
+
const { error, loading, data } = useQuery(getPriceSummaryQuery, {
|
|
65
|
+
fetchPolicy: 'cache-and-network',
|
|
66
|
+
nextFetchPolicy: 'cache-first',
|
|
67
|
+
skip: !cartId,
|
|
68
|
+
variables: {
|
|
69
|
+
cartId
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const [
|
|
74
|
+
initCheckoutSplitCart,
|
|
75
|
+
{
|
|
76
|
+
loading: initCheckoutSplitCartLoading,
|
|
77
|
+
data: initCheckoutSplitCartData,
|
|
78
|
+
error: initCheckoutSplitCartError,
|
|
79
|
+
called: initCheckoutSplitCartCalled
|
|
80
|
+
}
|
|
81
|
+
] = useMutation(initCheckoutSplitCartMutation);
|
|
82
|
+
|
|
83
|
+
const [fetchCartId] = useMutation(createCartMutation);
|
|
84
|
+
|
|
85
|
+
const handleProceedToCheckout = useCallback(async(props) => {
|
|
86
|
+
const { sellerUrl } = props;
|
|
87
|
+
|
|
88
|
+
// await initCheckoutSplitCart({
|
|
89
|
+
// variables: {
|
|
90
|
+
// input: {
|
|
91
|
+
// seller_url: sellerUrl,
|
|
92
|
+
// cart_id: cartId
|
|
93
|
+
// }
|
|
94
|
+
// }
|
|
95
|
+
// });
|
|
96
|
+
|
|
97
|
+
await createSellerCart({ initCheckoutSplitCart, sellerUrl });
|
|
98
|
+
|
|
99
|
+
// console.log('initCheckoutSplitCartData')
|
|
100
|
+
// console.log(initCheckoutSplitCartData)
|
|
101
|
+
|
|
102
|
+
await removeCart();
|
|
103
|
+
await apolloClient.clearCacheData(apolloClient, 'cart');
|
|
104
|
+
|
|
105
|
+
await createCart({
|
|
106
|
+
fetchCartId
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
history.push('/checkout');
|
|
110
|
+
}, [history, createSellerCart, fetchCartId, createCart, apolloClient, removeCart, cartId, initCheckoutSplitCart, initCheckoutSplitCartData]);
|
|
111
|
+
|
|
112
|
+
const handleEnterKeyPress = useCallback(() => {
|
|
113
|
+
event => {
|
|
114
|
+
if (event.key === 'Enter') {
|
|
115
|
+
handleProceedToCheckout();
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}, [handleProceedToCheckout]);
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
handleProceedToCheckout,
|
|
122
|
+
handleEnterKeyPress,
|
|
123
|
+
hasError: !!error,
|
|
124
|
+
hasItems: data && !!data.cart.items.length,
|
|
125
|
+
isCheckout,
|
|
126
|
+
isLoading: !!loading,
|
|
127
|
+
flatData: flattenData(data)
|
|
128
|
+
};
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
/** JSDocs type definitions */
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Query data flattened into a simple object.
|
|
135
|
+
*
|
|
136
|
+
* @typedef {Object} FlattenedData
|
|
137
|
+
*
|
|
138
|
+
* @property {String} subtotal Cart subtotal (excluding tax)
|
|
139
|
+
* @property {String} total Cart grand total
|
|
140
|
+
* @property {Array<Object>} discounts Applied discounts to the cart
|
|
141
|
+
* @property {Array<Object>} giftCards Gift cards applied to the cart
|
|
142
|
+
* @property {Array<Object>} giftOptions Gift Options applied to the cart
|
|
143
|
+
* @property {Array<Object>} taxes Taxes applied to the cart
|
|
144
|
+
* @property {Array<Object>} shipping Shipping addresses associated with this cart
|
|
145
|
+
*/
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* GraphQL queries for price summary component.
|
|
149
|
+
*
|
|
150
|
+
* @typedef {Object} PriceSummaryQueries
|
|
151
|
+
*
|
|
152
|
+
* @property {GraphQLAST} getPriceSummary Query to get the price summary for a cart
|
|
153
|
+
*
|
|
154
|
+
* @see [priceSummary.js]{@link https://github.com/magento/pwa-studio/blob/develop/packages/venia-ui/lib/components/CartPage/PriceSummary/priceSummary.js}
|
|
155
|
+
* for the queries used in Venia.
|
|
156
|
+
*/
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Props used for rendering a price summary component.
|
|
160
|
+
*
|
|
161
|
+
* @typedef {Object} PriceSummaryTalonProps
|
|
162
|
+
*
|
|
163
|
+
* @property {function} handleProceedToCheckout Callback function which navigates the browser to the checkout
|
|
164
|
+
* * @property {function} handleEnterKeyPress Callback function which navigates the browser to the checkout at the press of enter key
|
|
165
|
+
* @property {boolean} hasError True if a GraphQL query returns an error. False otherwise.
|
|
166
|
+
* @property {boolean} hasItems True if the cart has any items. False otherwise.
|
|
167
|
+
* @property {boolean} isLoading True while the GraphQL query is still in flight. False otherwise.
|
|
168
|
+
* @property {FlattenedData} flatData Query data that has been flattened into a simple object
|
|
169
|
+
*
|
|
170
|
+
*/
|
|
@@ -44,6 +44,19 @@ const Adapter = props => {
|
|
|
44
44
|
// const getWebsiteByUserIp = {
|
|
45
45
|
// countryCode: 'SG'
|
|
46
46
|
// }
|
|
47
|
+
|
|
48
|
+
// Check split cart
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
if (websiteCodeInUrl) {
|
|
51
|
+
setVerifyUserIp(false);
|
|
52
|
+
|
|
53
|
+
storage.removeItem('access_base_website');
|
|
54
|
+
|
|
55
|
+
routerProps.basename = websiteCodeInUrl != process.env.WEBSITE_CODE ? '/'+websiteCodeInUrl : '/';
|
|
56
|
+
|
|
57
|
+
setNewRouterProps(routerProps);
|
|
58
|
+
}
|
|
59
|
+
}, [websiteCodeInUrl])
|
|
47
60
|
|
|
48
61
|
useEffect(() => {
|
|
49
62
|
if (websiteCodeInUrl) {
|
|
@@ -28,7 +28,7 @@ import cn from 'classnames';
|
|
|
28
28
|
* import PriceSummary from "@magento/venia-ui/lib/components/CartPage/PriceSummary";
|
|
29
29
|
*/
|
|
30
30
|
const PriceSummary = props => {
|
|
31
|
-
const { isUpdating } = props;
|
|
31
|
+
const { isUpdating, sellerUrl } = props;
|
|
32
32
|
const classes = useStyle(defaultClasses, props.classes);
|
|
33
33
|
const talonProps = usePriceSummary();
|
|
34
34
|
|
|
@@ -91,7 +91,7 @@ const PriceSummary = props => {
|
|
|
91
91
|
<Button
|
|
92
92
|
disabled={isPriceUpdating}
|
|
93
93
|
priority={'high'}
|
|
94
|
-
onClick={handleProceedToCheckout}
|
|
94
|
+
onClick={() => handleProceedToCheckout({ sellerUrl })}
|
|
95
95
|
onKeyDown={handleEnterKeyPress}
|
|
96
96
|
data-cy="PriceSummary-checkoutButton"
|
|
97
97
|
classes={{
|
|
@@ -100,7 +100,7 @@ const PriceSummary = props => {
|
|
|
100
100
|
}}
|
|
101
101
|
>
|
|
102
102
|
<FormattedMessage
|
|
103
|
-
id={'
|
|
103
|
+
id={'splitCart.checkoutButton'}
|
|
104
104
|
defaultMessage={'Checkout'}
|
|
105
105
|
/>
|
|
106
106
|
</Button>
|
|
@@ -108,14 +108,8 @@ const PriceSummary = props => {
|
|
|
108
108
|
) : null;
|
|
109
109
|
|
|
110
110
|
return (
|
|
111
|
-
<div className={cn(classes.root, '
|
|
112
|
-
<div>
|
|
113
|
-
<p className='text-[16px] front font-medium mb-4'>
|
|
114
|
-
<FormattedMessage
|
|
115
|
-
id={'priceSummary.summaryLabel'}
|
|
116
|
-
defaultMessage={'Summary'}
|
|
117
|
-
/>
|
|
118
|
-
</p>
|
|
111
|
+
<div className={cn(classes.root, 'pb-6 px-3')} data-cy="PriceSummary-root">
|
|
112
|
+
{/* <div>
|
|
119
113
|
<ul>
|
|
120
114
|
<li className={classes.lineItems}>
|
|
121
115
|
<span
|
|
@@ -137,71 +131,8 @@ const PriceSummary = props => {
|
|
|
137
131
|
/>
|
|
138
132
|
</span>
|
|
139
133
|
</li>
|
|
140
|
-
<DiscountSummary
|
|
141
|
-
classes={{
|
|
142
|
-
lineItems: classes.lineItems,
|
|
143
|
-
lineItemLabel: classes.lineItemLabel,
|
|
144
|
-
price: priceClass
|
|
145
|
-
}}
|
|
146
|
-
data={discounts}
|
|
147
|
-
/>
|
|
148
|
-
<li className={classes.lineItems}>
|
|
149
|
-
<GiftCardSummary
|
|
150
|
-
classes={{
|
|
151
|
-
lineItemLabel: classes.lineItemLabel,
|
|
152
|
-
price: priceClass
|
|
153
|
-
}}
|
|
154
|
-
data={giftCards}
|
|
155
|
-
/>
|
|
156
|
-
</li>
|
|
157
|
-
<li className={classes.lineItems}>
|
|
158
|
-
<GiftOptionsSummary
|
|
159
|
-
classes={{
|
|
160
|
-
lineItemLabel: classes.lineItemLabel,
|
|
161
|
-
price: priceClass
|
|
162
|
-
}}
|
|
163
|
-
data={giftOptions}
|
|
164
|
-
/>
|
|
165
|
-
</li>
|
|
166
|
-
<li className={classes.lineItems}>
|
|
167
|
-
<TaxSummary
|
|
168
|
-
classes={{
|
|
169
|
-
lineItemLabel: classes.lineItemLabel,
|
|
170
|
-
price: priceClass
|
|
171
|
-
}}
|
|
172
|
-
data={taxes}
|
|
173
|
-
isCheckout={isCheckout}
|
|
174
|
-
/>
|
|
175
|
-
</li>
|
|
176
|
-
<li className={classes.lineItems}>
|
|
177
|
-
<ShippingSummary
|
|
178
|
-
classes={{
|
|
179
|
-
lineItemLabel: classes.lineItemLabel,
|
|
180
|
-
price: priceClass
|
|
181
|
-
}}
|
|
182
|
-
data={shipping}
|
|
183
|
-
isCheckout={isCheckout}
|
|
184
|
-
/>
|
|
185
|
-
</li>
|
|
186
|
-
<li className={classes.lineItems}>
|
|
187
|
-
<span
|
|
188
|
-
data-cy="PriceSummary-totalLabel"
|
|
189
|
-
className={classes.totalLabel}
|
|
190
|
-
>
|
|
191
|
-
{totalPriceLabel}
|
|
192
|
-
</span>
|
|
193
|
-
<span
|
|
194
|
-
data-cy="PriceSummary-totalValue"
|
|
195
|
-
className={totalPriceClass}
|
|
196
|
-
>
|
|
197
|
-
<Price
|
|
198
|
-
value={total.value}
|
|
199
|
-
currencyCode={total.currency}
|
|
200
|
-
/>
|
|
201
|
-
</span>
|
|
202
|
-
</li>
|
|
203
134
|
</ul>
|
|
204
|
-
</div>
|
|
135
|
+
</div> */}
|
|
205
136
|
{proceedToCheckoutButton}
|
|
206
137
|
</div>
|
|
207
138
|
);
|
package/src/overwrites/venia-ui/lib/components/CartPage/PriceSummary/priceSummary.module.css
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
.root {
|
|
1
|
+
.root {
|
|
2
|
+
text-align: right;
|
|
3
|
+
}
|
|
2
4
|
|
|
3
5
|
.errorText {
|
|
4
6
|
composes: leading-normal from global;
|
|
@@ -46,6 +48,6 @@
|
|
|
46
48
|
composes: inline-flex from global;
|
|
47
49
|
composes: justify-center from global;
|
|
48
50
|
composes: mt-xs from global;
|
|
49
|
-
|
|
51
|
+
width: 20%;
|
|
50
52
|
min-height: 5.5rem;
|
|
51
53
|
}
|
|
@@ -122,7 +122,7 @@ const Product = props => {
|
|
|
122
122
|
/>
|
|
123
123
|
</Link>
|
|
124
124
|
<div className='flex flex-col'>
|
|
125
|
-
<div className={cn(classes.name, 'text-[14px] font-
|
|
125
|
+
<div className={cn(classes.name, 'text-[14px] font-normal max-w-[260px]')} data-cy="Product-name">
|
|
126
126
|
<Link to={itemLink}>{name}</Link>
|
|
127
127
|
</div>
|
|
128
128
|
<ProductOptions
|
|
@@ -5,7 +5,7 @@ import { useProductListing } from '@magento/peregrine/lib/talons/CartPage/Produc
|
|
|
5
5
|
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
6
6
|
import LoadingIndicator from '@magento/venia-ui/lib/components/LoadingIndicator';
|
|
7
7
|
import defaultClasses from './productListing.module.css';
|
|
8
|
-
import
|
|
8
|
+
import ProductListingBySeller from '../ProductListingBySeller/productListingBySeller';
|
|
9
9
|
import ErrorMessage from './errorMessage';
|
|
10
10
|
import cn from 'classnames';
|
|
11
11
|
|
|
@@ -29,7 +29,9 @@ const ProductListing = props => {
|
|
|
29
29
|
const {
|
|
30
30
|
onAddToWishlistSuccess,
|
|
31
31
|
setIsCartUpdating,
|
|
32
|
-
fetchCartDetails
|
|
32
|
+
fetchCartDetails,
|
|
33
|
+
isCartUpdating,
|
|
34
|
+
hasItems
|
|
33
35
|
} = props;
|
|
34
36
|
|
|
35
37
|
const talonProps = useProductListing();
|
|
@@ -56,34 +58,53 @@ const ProductListing = props => {
|
|
|
56
58
|
);
|
|
57
59
|
}
|
|
58
60
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
// Grouping berdasarkan seller_id dengan data seller di atas
|
|
62
|
+
const groupedItems = items.reduce((acc, item) => {
|
|
63
|
+
if (!item.seller) {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const { seller_id, seller_name, seller_url } = item.seller;
|
|
68
|
+
|
|
69
|
+
if (!acc[seller_id]) {
|
|
70
|
+
acc[seller_id] = {
|
|
71
|
+
seller: {
|
|
72
|
+
seller_id,
|
|
73
|
+
seller_name,
|
|
74
|
+
seller_url
|
|
75
|
+
},
|
|
76
|
+
items: []
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
acc[seller_id].items.push(item);
|
|
81
|
+
return acc;
|
|
82
|
+
}, {});
|
|
83
|
+
|
|
84
|
+
// Ubah hasil ke dalam array
|
|
85
|
+
const itemsBySeller = Object.values(groupedItems);
|
|
86
|
+
|
|
87
|
+
if (itemsBySeller.length) {
|
|
88
|
+
const productBySellerComponents = itemsBySeller.map((sellerItems, index) => (
|
|
89
|
+
<ProductListingBySeller
|
|
90
|
+
onAddToWishlistSuccess={onAddToWishlistSuccess}
|
|
91
|
+
activeEditItem={activeEditItem}
|
|
92
|
+
isLoading={isLoading}
|
|
93
|
+
hasItems={hasItems}
|
|
94
|
+
key={index}
|
|
95
|
+
error={error}
|
|
64
96
|
setActiveEditItem={setActiveEditItem}
|
|
65
|
-
setIsCartUpdating={setIsCartUpdating}
|
|
66
|
-
onAddToWishlistSuccess={onAddToWishlistSuccess}
|
|
67
|
-
fetchCartDetails={fetchCartDetails}
|
|
68
97
|
wishlistConfig={wishlistConfig}
|
|
69
|
-
|
|
98
|
+
setIsCartUpdating={setIsCartUpdating}
|
|
99
|
+
fetchCartDetails={fetchCartDetails}
|
|
100
|
+
seller={sellerItems.seller}
|
|
101
|
+
isCartUpdating={isCartUpdating}
|
|
102
|
+
items={sellerItems.items} />
|
|
70
103
|
));
|
|
71
104
|
|
|
72
105
|
return (
|
|
73
106
|
<Fragment>
|
|
74
|
-
|
|
75
|
-
<ul className={cn(classes.root, 'border border-gray-100 rounded-md')} data-cy="ProductListing-root">
|
|
76
|
-
<div className='px-4'>
|
|
77
|
-
{productComponents}
|
|
78
|
-
</div>
|
|
79
|
-
</ul>
|
|
80
|
-
<Suspense fallback={null}>
|
|
81
|
-
<EditModal
|
|
82
|
-
item={activeEditItem}
|
|
83
|
-
setIsCartUpdating={setIsCartUpdating}
|
|
84
|
-
setActiveEditItem={setActiveEditItem}
|
|
85
|
-
/>
|
|
86
|
-
</Suspense>
|
|
107
|
+
{productBySellerComponents}
|
|
87
108
|
</Fragment>
|
|
88
109
|
);
|
|
89
110
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './productListingBySeller';
|