@riosst100/pwa-marketplace 2.9.3 → 2.9.5

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.
Files changed (37) hide show
  1. package/i18n/en_US.json +1 -0
  2. package/i18n/id_ID.json +1 -0
  3. package/package.json +1 -1
  4. package/src/componentOverrideMapping.js +2 -1
  5. package/src/components/ConfirmEmailPage/confirmEmail.js +76 -0
  6. package/src/components/ConfirmEmailPage/confirmEmail.module.css +71 -0
  7. package/src/components/ConfirmEmailPage/index.js +1 -0
  8. package/src/components/FavoriteSellerPage/favoriteSeller.js +0 -1
  9. package/src/components/FavoriteSellerPage/item.js +0 -2
  10. package/src/components/OrderDetail/components/itemsOrdered.js +94 -82
  11. package/src/components/OrderDetail/orderDetail.js +102 -86
  12. package/src/components/SubCategory/subCategory.js +1 -1
  13. package/src/components/VerifyEmailPage/verifyEmail.js +33 -10
  14. package/src/intercept.js +8 -1
  15. package/src/overwrites/peregrine/lib/talons/CartPage/PriceSummary/usePriceSummary.js +2 -2
  16. package/src/overwrites/peregrine/lib/talons/CheckoutPage/useCheckoutPage.js +43 -2
  17. package/src/overwrites/peregrine/lib/talons/FilterSidebar/useFilterSidebar.js +4 -1
  18. package/src/overwrites/peregrine/lib/talons/OrderHistoryPage/orderHistoryPage.gql.js +116 -0
  19. package/src/overwrites/peregrine/lib/talons/RootComponents/Category/useCategoryContent.js +7 -0
  20. package/src/overwrites/venia-ui/lib/components/AccountInformationPage/DeleteAccount.js +5 -37
  21. package/src/overwrites/venia-ui/lib/components/Adapter/adapter.js +3 -1
  22. package/src/overwrites/venia-ui/lib/components/Breadcrumbs/breadcrumbs.js +53 -58
  23. package/src/overwrites/venia-ui/lib/components/CheckoutPage/OrderConfirmationPage/orderConfirmationPage.js +68 -39
  24. package/src/overwrites/venia-ui/lib/components/CheckoutPage/checkoutPage.js +1 -1
  25. package/src/overwrites/venia-ui/lib/components/OrderHistoryPage/orderHistoryPage.js +10 -2
  26. package/src/overwrites/venia-ui/lib/components/OrderHistoryPage/orderRow.js +91 -78
  27. package/src/overwrites/venia-ui/lib/components/OrderHistoryPage/orderRow.module.css +3 -3
  28. package/src/overwrites/venia-ui/lib/components/StoreCodeRoute/storeCodeRoute.js +1 -1
  29. package/src/talons/AccountInformationPage/deleteAccount.gql.js +23 -0
  30. package/src/talons/AccountInformationPage/useDeleteAccount.js +98 -0
  31. package/src/talons/ConfirmEmailPage/confirmEmailPage.gql.js +20 -0
  32. package/src/talons/ConfirmEmailPage/useConfirmEmailPage.js +78 -0
  33. package/src/talons/OrderHistoryPage/useOrderHistoryPage.js +115 -0
  34. package/src/talons/ShopBy/useShopBy.js +12 -2
  35. package/src/talons/VerifyEmailPage/useVerifyEmailPage.js +73 -0
  36. package/src/talons/VerifyEmailPage/verifyEmailPage.gql.js +36 -0
  37. package/src/talons/WebsiteSwitcher/useWebsiteSwitcher.js +13 -2
@@ -2,49 +2,17 @@ import React, { useState } from 'react';
2
2
  import { FormattedMessage } from 'react-intl';
3
3
  import Button from '@magento/venia-ui/lib/components/Button';
4
4
  import { Message } from '@magento/venia-ui/lib/components/Field';
5
-
6
- // Dummy mutation placeholder
7
- const useDeleteAccount = () => {
8
- const [loading, setLoading] = useState(false);
9
- const [error, setError] = useState(null);
10
- const [success, setSuccess] = useState(false);
11
-
12
- const deleteAccount = async () => {
13
- setLoading(true);
14
- setError(null);
15
- setSuccess(false);
16
- // Simulate API call
17
- setTimeout(() => {
18
- setLoading(false);
19
- setSuccess(true);
20
- }, 1500);
21
- };
22
-
23
- return {
24
- loading,
25
- error,
26
- success,
27
- deleteAccount
28
- };
29
- };
5
+ import { useDeleteAccount } from '@riosst100/pwa-marketplace/src/talons/AccountInformationPage/useDeleteAccount';
30
6
 
31
7
  const DeleteAccount = () => {
32
8
  const [confirm, setConfirm] = useState(false);
33
9
  const [agreement, setAgreement] = useState(false);
34
- const { loading, error, success, deleteAccount } = useDeleteAccount();
10
+
11
+ const { loading, error, success, handleDeleteAccount } = useDeleteAccount();
12
+
35
13
  const handleChange = (event) => {
36
14
  setAgreement(event.target.checked);
37
15
  }
38
- if (success) {
39
- return (
40
- <Message type="success">
41
- <FormattedMessage
42
- id="deleteAccount.success"
43
- defaultMessage="Your account has been deleted."
44
- />
45
- </Message>
46
- );
47
- }
48
16
 
49
17
  return (
50
18
  <div style={{ marginTop: 32, border: '1px solid #f87171', padding: 24, borderRadius: 8, background: '#fef2f2' }}>
@@ -91,7 +59,7 @@ const DeleteAccount = () => {
91
59
  <Button
92
60
  priority="high"
93
61
  disabled={loading || !agreement}
94
- onClick={deleteAccount}
62
+ onClick={handleDeleteAccount}
95
63
  style={{ marginRight: 8, textTransform: 'none' }}
96
64
  >
97
65
  <FormattedMessage
@@ -61,8 +61,10 @@ const Adapter = props => {
61
61
  useEffect(() => {
62
62
  if (!websiteCodeInUrl && getWebsiteByUserIp) {
63
63
  setVerifyUserIp(false);
64
+
65
+ const search = location.search;
64
66
 
65
- const query = new URLSearchParams(location.search);
67
+ const query = new URLSearchParams(search);
66
68
  const isAccessBaseWebsite = query.get('access_base_website') || (
67
69
  storage.getItem('access_base_website') || null
68
70
  );
@@ -26,7 +26,9 @@ const Breadcrumbs = props => {
26
26
 
27
27
  const talonProps = useBreadcrumbs({ categoryId });
28
28
 
29
- const DELIMITER = <ArrowRight2 size={13} className='inline-flex text-gray-200' />
29
+ const location = useLocation(); // dipindah ke atas sebelum conditional return
30
+
31
+ const DELIMITER = <ArrowRight2 size={13} className='inline-flex text-gray-200' />;
30
32
 
31
33
  const {
32
34
  currentCategory,
@@ -39,13 +41,15 @@ const Breadcrumbs = props => {
39
41
 
40
42
  // For all links generate a fragment like "/ Text"
41
43
  const links = useMemo(() => {
42
- return normalizedData.map(({ text, path }) => {
44
+ return normalizedData.map(({ text, path }, index) => {
43
45
  if (text == "dCollectible Card Games") {
44
46
  return '';
45
47
  }
46
-
48
+
49
+ console.log('index', index);
50
+
47
51
  return (
48
- <Fragment key={text}>
52
+ <Fragment key={index}>
49
53
  <span className={classes.divider}>{DELIMITER}</span>
50
54
  <Link
51
55
  className={classes.link}
@@ -74,14 +78,11 @@ const Breadcrumbs = props => {
74
78
  );
75
79
  }
76
80
 
77
- const filterBreadcrumbsElement = [];
81
+ let filterBreadcrumbsElement = []; // ✅ pakai let agar bisa di-push
78
82
 
79
83
  const lastIndex = currentFilter ? currentFilter.length - 1 : 0;
80
- // const filterpath = ;
81
-
82
- const { search } = useLocation();
83
84
 
84
- // const previousSearch = useRef(search);
85
+ const { search } = location;
85
86
 
86
87
  const removeShopbyParam = (url) => {
87
88
  const urlParts = url.split("?"); // Pisahkan URL sebelum dan sesudah tanda tanya
@@ -98,78 +99,72 @@ const Breadcrumbs = props => {
98
99
 
99
100
  // Gabungkan URL dasar dengan query string yang telah dimodifikasi
100
101
  return newQueryString ? `${baseUrl}?${newQueryString}` : baseUrl;
101
- }
102
+ };
102
103
 
103
104
  const params = removeShopbyParam(search);
104
-
105
+
105
106
  currentFilter && currentFilter.length && currentFilter.map((filter, index) => {
106
107
  currentProduct ? (
107
108
  filterBreadcrumbsElement.push(
108
- <>
109
- <span className={classes.divider}>{DELIMITER}</span>
110
- <Link
111
- key={index}
112
- className={classes.link}
113
- to={resourceUrl('/'+currentCategoryPath)}
114
- onClick={handleClick}
115
- >
116
- {filter.label}
117
- </Link>
118
- </>
119
- )
120
- ) : (
121
- customPage ? (
122
- filterBreadcrumbsElement.push(
123
- <>
109
+ <span key={index}>
124
110
  <span className={classes.divider}>{DELIMITER}</span>
125
111
  <Link
126
- key={index}
127
112
  className={classes.link}
128
- to={resourceUrl('/'+currentCategoryPath+params)}
113
+ to={resourceUrl('/' + currentCategoryPath)}
129
114
  onClick={handleClick}
130
115
  >
131
116
  {filter.label}
132
117
  </Link>
133
- </>
118
+ </span>
119
+ )
120
+ ) : (
121
+ customPage ? (
122
+ filterBreadcrumbsElement.push(
123
+ <span key={index}>
124
+ <span className={classes.divider}>{DELIMITER}</span>
125
+ <Link
126
+ className={classes.link}
127
+ to={resourceUrl('/' + currentCategoryPath + params)}
128
+ onClick={handleClick}
129
+ >
130
+ {filter.label}
131
+ </Link>
132
+ </span>
134
133
  )
135
134
  ) : filterBreadcrumbsElement.push(
136
135
  index == lastIndex ?
137
- <>
138
- <span className={classes.divider}>{DELIMITER}</span>
139
- <span key={index} className={cn(classes.currentCategory, 'text-blue-700 font-medium')}>{filter.label}</span>
140
- </> : <>
141
- <span className={classes.divider}>{DELIMITER}</span>
142
- <Link
143
- key={index}
144
- className={classes.link}
145
- to={resourceUrl('/'+currentCategoryPath+params)}
146
- onClick={handleClick}
147
- >
148
- {filter.label}
149
- </Link>
150
- </>
136
+ <span key={index}>
137
+ <span className={classes.divider}>{DELIMITER}</span>
138
+ <span className={cn(classes.currentCategory, 'text-blue-700 font-medium')}>{filter.label}</span>
139
+ </span> : <span key={index}>
140
+ <span className={classes.divider}>{DELIMITER}</span>
141
+ <Link
142
+ className={classes.link}
143
+ to={resourceUrl('/' + currentCategoryPath + params)}
144
+ onClick={handleClick}
145
+ >
146
+ {filter.label}
147
+ </Link>
148
+ </span>
151
149
  )
152
150
  );
153
151
  });
154
152
 
155
- // If we have a "currentProduct" it means we're on a PDP so we want the last
156
- // category text to be a link. If we don't have a "currentProduct" we're on
157
- // a category page so it should be regular text.
158
153
  const currentCategoryLink = currentCategory == "dCollectible Card Games" ? '' : (customPage || currentProduct || currentFilter && currentFilter.length ? (
159
154
  <>
160
- <span className={classes.divider}>{DELIMITER}</span>
161
- <Link
162
- className={classes.link}
163
- to={'/'+resourceUrl(currentCategoryPath)}
164
- onClick={handleClick}
165
- >
166
- {currentCategory}
167
- </Link>
155
+ <span className={classes.divider}>{DELIMITER}</span>
156
+ <Link
157
+ className={classes.link}
158
+ to={'/' + resourceUrl(currentCategoryPath)}
159
+ onClick={handleClick}
160
+ >
161
+ {currentCategory}
162
+ </Link>
168
163
  </>
169
164
  ) : (
170
165
  <>
171
- <span className={classes.divider}>{DELIMITER}</span>
172
- <span className={cn(classes.currentCategory, 'text-blue-700 font-medium')}>{currentCategory}</span>
166
+ <span className={classes.divider}>{DELIMITER}</span>
167
+ <span className={cn(classes.currentCategory, 'text-blue-700 font-medium')}>{currentCategory}</span>
173
168
  </>
174
169
  ));
175
170
 
@@ -186,7 +181,7 @@ const Breadcrumbs = props => {
186
181
  <span className={classes.text}>{customPage}</span>
187
182
  </Fragment>
188
183
  ) : null;
189
-
184
+
190
185
  return (
191
186
  <div className={classes.root} aria-live="polite" aria-busy="false">
192
187
  <Link className={classes.link} to="/">
@@ -15,9 +15,27 @@ const OrderConfirmationPage = props => {
15
15
  const { data, orderNumber } = props;
16
16
  const { formatMessage } = useIntl();
17
17
 
18
- const talonProps = useOrderConfirmationPage({
19
- data
20
- });
18
+ // If data is not available (e.g., after external redirect without snapshot),
19
+ // render a minimal confirmation page.
20
+ const hasData =
21
+ data &&
22
+ data.cart &&
23
+ Array.isArray(data.cart.shipping_addresses) &&
24
+ data.cart.shipping_addresses.length > 0;
25
+
26
+ const talonProps = hasData
27
+ ? useOrderConfirmationPage({ data })
28
+ : { flatData: {
29
+ city: '',
30
+ country: '',
31
+ email: '',
32
+ firstname: '',
33
+ lastname: '',
34
+ postcode: '',
35
+ region: '',
36
+ shippingMethod: '',
37
+ street: []
38
+ }, isSignedIn: true };
21
39
 
22
40
  const { flatData, isSignedIn } = talonProps;
23
41
 
@@ -33,7 +51,7 @@ const OrderConfirmationPage = props => {
33
51
  street
34
52
  } = flatData;
35
53
 
36
- const streetRows = street.map((row, index) => {
54
+ const streetRows = (street || []).map((row, index) => {
37
55
  return (
38
56
  <span key={index} className={classes.addressStreet}>
39
57
  {row}
@@ -51,6 +69,13 @@ const OrderConfirmationPage = props => {
51
69
  behavior: 'smooth'
52
70
  });
53
71
  }
72
+ // Best-effort cleanup of stored snapshot after successful view
73
+ try {
74
+ if (orderNumber) {
75
+ const key = `orderConfirmationSnapshot:${orderNumber}`;
76
+ globalThis.localStorage && globalThis.localStorage.removeItem(key);
77
+ }
78
+ } catch (_) {}
54
79
  }, []);
55
80
 
56
81
  const createAccountForm = !isSignedIn ? (
@@ -109,42 +134,46 @@ const OrderConfirmationPage = props => {
109
134
  </Link>
110
135
  </div>
111
136
  </div>
112
- <div className={classes.detailsGrid}>
113
- <div className={classes.card}>
114
- <div
115
- data-cy="OrderConfirmationPage-shippingInfoHeading"
116
- className={classes.cardHeading}
117
- >
118
- <FormattedMessage
119
- id={'global.shippingInformation'}
120
- defaultMessage={'Shipping Information'}
121
- />
137
+ {hasData ? (
138
+ <>
139
+ <div className={classes.detailsGrid}>
140
+ <div className={classes.card}>
141
+ <div
142
+ data-cy="OrderConfirmationPage-shippingInfoHeading"
143
+ className={classes.cardHeading}
144
+ >
145
+ <FormattedMessage
146
+ id={'global.shippingInformation'}
147
+ defaultMessage={'Shipping Information'}
148
+ />
149
+ </div>
150
+ <div className={classes.shippingInfo}>
151
+ <span className={classes.email}>{email}</span>
152
+ <span className={classes.name}>{nameString}</span>
153
+ {streetRows}
154
+ <span className={classes.addressAdditional}>
155
+ {additionalAddressString}
156
+ </span>
157
+ </div>
158
+ </div>
159
+ <div className={classes.card}>
160
+ <div
161
+ data-cy="OrderConfirmationPage-shippingMethodHeading"
162
+ className={classes.cardHeading}
163
+ >
164
+ <FormattedMessage
165
+ id={'global.shippingMethod'}
166
+ defaultMessage={'Shipping Method'}
167
+ />
168
+ </div>
169
+ <div className={classes.shippingMethod}>{shippingMethod}</div>
170
+ </div>
122
171
  </div>
123
- <div className={classes.shippingInfo}>
124
- <span className={classes.email}>{email}</span>
125
- <span className={classes.name}>{nameString}</span>
126
- {streetRows}
127
- <span className={classes.addressAdditional}>
128
- {additionalAddressString}
129
- </span>
172
+ <div className={classes.itemsReview}>
173
+ <ItemsReview data={data} />
130
174
  </div>
131
- </div>
132
- <div className={classes.card}>
133
- <div
134
- data-cy="OrderConfirmationPage-shippingMethodHeading"
135
- className={classes.cardHeading}
136
- >
137
- <FormattedMessage
138
- id={'global.shippingMethod'}
139
- defaultMessage={'Shipping Method'}
140
- />
141
- </div>
142
- <div className={classes.shippingMethod}>{shippingMethod}</div>
143
- </div>
144
- </div>
145
- <div className={classes.itemsReview}>
146
- <ItemsReview data={data} />
147
- </div>
175
+ </>
176
+ ) : null}
148
177
  <div
149
178
  data-cy="OrderConfirmationPage-additionalText"
150
179
  className={classes.additionalText}
@@ -181,6 +210,6 @@ OrderConfirmationPage.propTypes = {
181
210
  additionalText: string,
182
211
  sidebarContainer: string
183
212
  }),
184
- data: object.isRequired,
213
+ data: object,
185
214
  orderNumber: string
186
215
  };
@@ -125,7 +125,7 @@ const CheckoutPage = props => {
125
125
  defaultMessage: 'Checkout'
126
126
  });
127
127
 
128
- if (orderNumber && orderDetailsData) {
128
+ if (orderNumber) {
129
129
  return (
130
130
  <OrderConfirmationPage
131
131
  data={orderDetailsData}
@@ -10,7 +10,7 @@ import { Form } from 'informed';
10
10
 
11
11
  import { useToasts } from '@magento/peregrine/lib/Toasts';
12
12
  import OrderHistoryContextProvider from '@magento/peregrine/lib/talons/OrderHistoryPage/orderHistoryContext';
13
- import { useOrderHistoryPage } from '@magento/peregrine/lib/talons/OrderHistoryPage/useOrderHistoryPage';
13
+ import { useOrderHistoryPage } from '@riosst100/pwa-marketplace/src/talons/OrderHistoryPage/useOrderHistoryPage';
14
14
 
15
15
  import { useStyle } from '@magento/venia-ui/lib/classify';
16
16
  import Button from '@magento/venia-ui/lib/components/Button';
@@ -24,6 +24,7 @@ import OrderRow from './orderRow';
24
24
  import ResetButton from './resetButton';
25
25
  import { SearchNormal } from 'iconsax-react';
26
26
  import cn from 'classnames';
27
+ import Pagination from '@riosst100/pwa-marketplace/src/overwrites/venia-ui/lib/components/Pagination';
27
28
 
28
29
  const errorIcon = (
29
30
  <Icon
@@ -46,7 +47,8 @@ const OrderHistoryPage = props => {
46
47
  isLoadingWithoutData,
47
48
  orders,
48
49
  pageInfo,
49
- searchText
50
+ searchText,
51
+ pageControl
50
52
  } = talonProps;
51
53
  const [, { addToast }] = useToasts();
52
54
  const { formatMessage } = useIntl();
@@ -205,6 +207,12 @@ const OrderHistoryPage = props => {
205
207
  <span className={classes.pageInfo}>{pageInfoLabel}</span>
206
208
  </div>
207
209
  {pageContents}
210
+ {/* Pagination Controls */}
211
+ <div className="mt-4">
212
+ {pageControl?.totalPages > 1 ? (
213
+ <Pagination pageControl={pageControl} />
214
+ ) : null}
215
+ </div>
208
216
  {loadMoreButton}
209
217
  </div>
210
218
  </OrderHistoryContextProvider >