@riosst100/pwa-marketplace 3.0.4 → 3.0.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.
Files changed (30) hide show
  1. package/package.json +1 -1
  2. package/src/componentOverrideMapping.js +1 -0
  3. package/src/components/CrossSeller/item.js +3 -4
  4. package/src/components/LinkToOtherStores/index.js +4 -4
  5. package/src/components/ProductListTab/productListTab.js +1 -1
  6. package/src/components/commons/Select/index.js +8 -4
  7. package/src/overwrites/peregrine/lib/talons/CartPage/PriceSummary/priceSummaryFragments.gql.js +3 -0
  8. package/src/overwrites/peregrine/lib/talons/CartPage/ProductListing/productListingFragments.gql.js +4 -0
  9. package/src/overwrites/peregrine/lib/talons/CheckoutPage/PaymentInformation/usePaymentMethods.js +84 -0
  10. package/src/overwrites/peregrine/lib/talons/CheckoutPage/checkoutPage.extended.gql.js +20 -1
  11. package/src/overwrites/peregrine/lib/talons/FilterSidebar/useFilterSidebar.js +3 -3
  12. package/src/overwrites/peregrine/lib/talons/ProductFullDetail/useProductFullDetail.js +7 -8
  13. package/src/overwrites/peregrine/lib/talons/RootComponents/Product/productDetailFragment.gql.js +5 -0
  14. package/src/overwrites/venia-ui/lib/components/Breadcrumbs/breadcrumbs.js +20 -1
  15. package/src/overwrites/venia-ui/lib/components/CartPage/ProductListing/product.js +41 -1
  16. package/src/overwrites/venia-ui/lib/components/CartPage/ProductListing/product.module.css +1 -1
  17. package/src/overwrites/venia-ui/lib/components/CartPage/ProductListingBySeller/productListingBySeller.js +41 -8
  18. package/src/overwrites/venia-ui/lib/components/CheckoutPage/ItemsReview/item.js +43 -2
  19. package/src/overwrites/venia-ui/lib/components/CheckoutPage/ItemsReview/item.module.css +36 -0
  20. package/src/overwrites/venia-ui/lib/components/CheckoutPage/ItemsReview/itemsReview.js +8 -2
  21. package/src/overwrites/venia-ui/lib/components/CheckoutPage/checkoutPage.js +7 -2
  22. package/src/overwrites/venia-ui/lib/components/FilterModal/CurrentFilters/currentFilters.js +1 -1
  23. package/src/overwrites/venia-ui/lib/components/FilterSidebar/filterSidebar.js +1 -1
  24. package/src/overwrites/venia-ui/lib/components/Gallery/item.js +2 -10
  25. package/src/overwrites/venia-ui/lib/components/Gallery/item.module.css +5 -4
  26. package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/customAttributes.js +10 -2
  27. package/src/overwrites/venia-ui/lib/components/ProductFullDetail/components/preOrderDetail.js +195 -37
  28. package/src/overwrites/venia-ui/lib/components/ProductFullDetail/productFullDetail.js +194 -63
  29. package/src/talons/ProductContent/productContent.gql.js +11 -1
  30. package/src/talons/ProductContent/useProductContent.js +14 -2
@@ -20,7 +20,7 @@ const CurrentFilters = props => {
20
20
  const { title, value } = item || {};
21
21
  const key = `${group}::${title}_${value}`;
22
22
 
23
- const customAttributeLandingPage = ['bricks_categories','sc_sports_categories','card_game', 'sc_baseball_release','auction','special_price','lof_preorder','sc_baseball_inserts','sc_baseball_parallel','sc_set_type'];
23
+ const customAttributeLandingPage = ['bricks_categories','sc_sports_categories','card_game', 'sc_baseball_release','auction','special_price','lof_preorder','card_pre_orders','sc_baseball_inserts','sc_baseball_parallel','sc_set_type'];
24
24
 
25
25
  if (!customAttributeLandingPage.includes(group)) {
26
26
  elements.push(
@@ -125,7 +125,7 @@ const FilterSidebar = props => {
125
125
  const groupName = filterNames.get(group);
126
126
  const frontendInput = filterFrontendInput.get(group);
127
127
 
128
- const hideFilters = ['card_game','bricks_categories','sc_sports_categories','trains','trains_locomotives','trains_supplies_type','lof_preorder','auction','special_price','sc_baseball_inserts','sc_baseball_parallel','sale','sc_set_type','sc_brands'];
128
+ const hideFilters = ['card_game','bricks_categories','sc_sports_categories','trains','trains_locomotives','trains_supplies_type','lof_preorder','card_pre_orders','auction','special_price','sc_baseball_inserts','sc_baseball_parallel','sale','sc_set_type','sc_brands'];
129
129
  if (!allowedFiltersArr?.length || filterState.size && allowedFiltersArr.length || !filterState.size && allowedFiltersArr.length && allowedFiltersArr.includes(group)) {
130
130
  if (!hideFilters.includes(group) && groupName && !group.includes('card_release') && !group.includes('card_set') && !group.includes('sc_set_name')) {
131
131
 
@@ -140,7 +140,7 @@ const GalleryItem = props => {
140
140
  data-cy="GalleryItem-name">{name}</span>
141
141
  {/* </Link> */}
142
142
  <div data-cy="GalleryItem-price" className={cn(classes.price, 'mb-2.5 pt-2.5')}>
143
- <p className='font-medium !text-[#f76b1c] text-[1.1rem] !mb-1 !leading-[14px]'>
143
+ <p className='font-medium !text-[#f76b1c] !mb-1'>
144
144
  <Price
145
145
  value={priceSource.value}
146
146
  currencyCode={priceSource.currency}
@@ -154,16 +154,8 @@ const GalleryItem = props => {
154
154
  </p> */}
155
155
  </div>
156
156
 
157
- <div data-cy="GalleryItem-Rating" className={cn('flex gap-[5px] items-center mb-2')}>
158
- <Star />
159
- <span className='text-[12px] leading-normal'>
160
- {rating_summary}
161
- </span>
162
- </div>
163
-
164
157
  <div data-cy="GalleryItem-Seller" className={cn('flex gap-[5px] items-center')}>
165
- <Verify size={17} className='text-blue-700' variant="Bold" />
166
- <span className='text-[12px] text-gray-300 leading-normal'>
158
+ <span className='text-[12px] text-gray-400 leading-normal'>
167
159
  {seller}
168
160
  </span>
169
161
  </div>
@@ -74,11 +74,11 @@
74
74
  }
75
75
 
76
76
  .name {
77
- composes: font-medium from global;
77
+ /* composes: font-medium from global; */
78
78
  composes: text-base from global;
79
79
  composes: mb-1 from global;
80
80
  display: -webkit-box;
81
- -webkit-line-clamp: 2;
81
+ -webkit-line-clamp: 3;
82
82
  -webkit-box-orient: vertical;
83
83
  overflow: hidden;
84
84
  line-height: normal;
@@ -87,13 +87,14 @@
87
87
  .name,
88
88
  .price {
89
89
  composes: text-colorDefault from global;
90
- composes: text-[14px] from global;
91
- composes: font-medium from global;
90
+ /* composes: text-[14px] from global; */
91
+ /* composes: font-medium from global; */
92
92
  min-height: 1rem;
93
93
  }
94
94
 
95
95
  .price {
96
96
  padding-top: 2.5;
97
+ composes: font-medium from global;
97
98
  }
98
99
 
99
100
  .unavailableContainer {
@@ -13,14 +13,22 @@ const CustomAttributes = props => {
13
13
  const { customAttributes, showLabels } = props;
14
14
  const classes = useStyle(defaultClasses, props.classes);
15
15
 
16
+ const systemAttributes = [
17
+ 'term_and_conditions',
18
+ 'sale',
19
+ 'sku'
20
+ ];
21
+
16
22
  const list = useMemo(
17
23
  () =>
18
24
  customAttributes.reduce((previousAttribute, currentAttribute) => {
25
+ console.log('currentAttribute',currentAttribute)
26
+ const attrCode = currentAttribute.attribute_metadata?.code;
19
27
  const usedInComponents =
20
28
  currentAttribute.attribute_metadata?.used_in_components ||
21
29
  [];
22
30
  // Visible on front attributes only
23
- if (usedInComponents.includes(IS_VISIBLE_ON_FRONT)) {
31
+ if (!systemAttributes.includes(attrCode) && usedInComponents.includes(IS_VISIBLE_ON_FRONT)) {
24
32
  const attributeContent = (
25
33
  <li
26
34
  key={currentAttribute.attribute_metadata.uid}
@@ -38,7 +46,7 @@ const CustomAttributes = props => {
38
46
 
39
47
  return previousAttribute;
40
48
  }, []),
41
- [classes, customAttributes, showLabels]
49
+ [classes, customAttributes, showLabels, systemAttributes]
42
50
  );
43
51
 
44
52
  if (list.length === 0) {
@@ -1,58 +1,216 @@
1
- import React, { useMemo } from 'react';
1
+ import React, { useEffect, useMemo, useState } from 'react';
2
2
  import cn from 'classnames';
3
3
  import Divider from '@riosst100/pwa-marketplace/src/components/Divider';
4
+ import Select from '@riosst100/pwa-marketplace/src/components/commons/Select';
4
5
 
5
6
  const preOrderInfo = (props) => {
6
- const { className, productDetails } = props
7
-
8
- const preorderData = productDetails ? productDetails.preorder : null;
7
+ const { className, preOrder, preOrderDate, preOrderDeposite, preOrderNote, preOrderPaymentType, releaseDate, onPaymentTypeChange, paymentTypeOptions = [] } = props;
9
8
 
10
- const isPreOrder = preorderData && preorderData.is_preorder ? true : false;
11
- const preOrderNotes = preorderData ? preorderData.preorder_notes : null;
12
- const preOrderAvailableDate = preorderData ? new Date(preorderData.preorder_availability) : null;
9
+ const isPreOrder = typeof preOrder === 'string'
10
+ ? preOrder.trim().toLowerCase() === 'pre orders'
11
+ : !!(preOrder && preOrder.is_preorder);
12
+
13
+ const normalizePaymentType = (value = '') => {
14
+ const normalized = value.toString().trim().toLowerCase();
15
+
16
+ if (normalized === 'full payment') {
17
+ return 'full';
18
+ }
19
+
20
+ if (normalized === 'deposit' || normalized === 'full') {
21
+ return normalized;
22
+ }
23
+
24
+ return '';
25
+ };
26
+
27
+ const initialPaymentType = useMemo(
28
+ () => normalizePaymentType(preOrderPaymentType),
29
+ [preOrderPaymentType]
30
+ );
31
+
32
+ const [selectedPaymentType, setSelectedPaymentType] = useState(initialPaymentType || 'full');
33
+
34
+ useEffect(() => {
35
+ setSelectedPaymentType(initialPaymentType || 'full');
36
+ }, [initialPaymentType]);
37
+
38
+ // Propagate initial and subsequent selection to parent so submit has value
39
+ useEffect(() => {
40
+ if (typeof onPaymentTypeChange === 'function' && selectedPaymentType) {
41
+ onPaymentTypeChange(selectedPaymentType);
42
+ }
43
+ }, [selectedPaymentType, onPaymentTypeChange]);
44
+
45
+ const normalizedPaymentOptions = useMemo(() => {
46
+ return paymentTypeOptions.reduce((acc, option) => {
47
+ const normalizedValue = normalizePaymentType(option.value);
48
+ if (!normalizedValue) {
49
+ return acc;
50
+ }
51
+
52
+ if (acc.find(item => item.value === normalizedValue)) {
53
+ return acc;
54
+ }
55
+
56
+ const label = option.label || (normalizedValue === 'full' ? 'Full Payment' : 'Deposit');
57
+ acc.push({ label, value: normalizedValue });
58
+ return acc;
59
+ }, []);
60
+ }, [paymentTypeOptions]);
61
+
62
+ const paymentOptions = useMemo(() => {
63
+ const optionsToUse = normalizedPaymentOptions;
64
+
65
+ if (!optionsToUse.length) {
66
+ return [];
67
+ }
68
+
69
+ if (initialPaymentType === 'full') {
70
+ return optionsToUse.filter(option => option.value === 'full');
71
+ }
72
+
73
+ if (initialPaymentType === 'deposit') {
74
+ return optionsToUse;
75
+ }
76
+
77
+ return optionsToUse;
78
+ }, [initialPaymentType, normalizedPaymentOptions]);
79
+
80
+ const handlePaymentTypeChange = (event) => {
81
+ if (!paymentOptions.length) {
82
+ return;
83
+ }
84
+
85
+ const nextValue = event.target.value;
86
+ const availableValues = paymentOptions.map(option => option.value);
87
+ const appliedValue = availableValues.includes(nextValue)
88
+ ? nextValue
89
+ : availableValues[0];
90
+
91
+ setSelectedPaymentType(appliedValue);
92
+
93
+ if (typeof onPaymentTypeChange === 'function') {
94
+ onPaymentTypeChange(appliedValue);
95
+ }
96
+ };
97
+
98
+ const formatDate = (value) => {
99
+ if (!value) {
100
+ return '-';
101
+ }
13
102
 
14
- const month = ["January","February","March","April","May","June","July","August","September","October","November","December"];
103
+ const parsed = value instanceof Date ? value : new Date(value);
104
+ if (Number.isNaN(parsed.getTime())) {
105
+ return '-';
106
+ }
107
+
108
+ const day = String(parsed.getDate()).padStart(2, '0');
109
+ const month = String(parsed.getMonth() + 1).padStart(2, '0');
110
+ const year = parsed.getFullYear();
111
+
112
+ return `${day}/${month}/${year}`;
113
+ };
114
+
115
+ const preOrderNotes = preOrderNote || null;
116
+ const preOrderAvailableDate = releaseDate || null;
117
+ const preOrderClosingDate = preOrderDate || null;
118
+
119
+ const normalizeDeposit = (value) => {
120
+ if (!value && value !== 0) {
121
+ return '-';
122
+ }
123
+
124
+ const numeric = typeof value === 'number'
125
+ ? value
126
+ : Number.parseFloat(value.toString().replace(/[^0-9.-]/g, ''));
127
+
128
+ if (Number.isNaN(numeric)) {
129
+ return value;
130
+ }
131
+
132
+ // Tampilkan sebagai persentase tanpa 0 di belakang koma dan tambahkan '%'
133
+ // Contoh: 10.00 -> '10%'; 12.5 -> '12.5%'; 12.50 -> '12.5%'
134
+ let str = numeric.toString();
135
+ if (str.includes('.')) {
136
+ // hapus trailing zeros di desimal
137
+ str = str.replace(/\.0+$/,'');
138
+ str = str.replace(/\.(\d*[1-9])0+$/,'.$1');
139
+ }
140
+ return `${str}%`;
141
+ };
142
+
143
+ const depositValue = normalizeDeposit(preOrderDeposite);
144
+ const showDepositRow = selectedPaymentType === 'deposit';
145
+
146
+ const isPreOrderClosed = (() => {
147
+ if (!preOrderClosingDate) return false;
148
+
149
+ const parsed = preOrderClosingDate instanceof Date
150
+ ? preOrderClosingDate
151
+ : new Date(preOrderClosingDate);
152
+
153
+ if (Number.isNaN(parsed.getTime())) return false;
154
+
155
+ parsed.setHours(23, 59, 59, 999);
156
+ return new Date().getTime() > parsed.getTime();
157
+ })();
15
158
 
16
159
  return isPreOrder ? (
17
160
  <>
18
161
  <div
19
162
  className={cn(
20
- 'flex flex-col border border-gray-100 rounded-lg p-5 gap-2.5',
163
+ 'flex flex-col border border-gray-100 rounded-lg p-5 m-4 gap-4 bg-white',
21
164
  className
22
165
  )}
23
166
  >
24
- <div className='flex flex-row justify-between gap-[20px]'>
25
- <div className='flex flex-col gap-2.5'>
26
- <div className='text-[14px] font-medium text-gray-500'>
27
- Release Date
28
- </div>
29
- <div className='text-[16px] font-medium text-colorDefault text-center'>
30
- {preOrderAvailableDate ? preOrderAvailableDate.getDate() + ', ' + month[preOrderAvailableDate.getMonth()] + ' ' + preOrderAvailableDate.getFullYear() : 'No Release Date.'}
31
- {/* 27, February 2024 */}
32
- </div>
167
+ <div className='text-[16px] font-semibold text-colorDefault'>
168
+ Pre Order Details
169
+ </div>
170
+ <div className='flex flex-col gap-3'>
171
+ {showDepositRow && (
172
+ <>
173
+ <div className='flex justify-between text-[13px] text-gray-600'>
174
+ <span className='font-medium text-gray-500'>Deposit:</span>
175
+ <span className='font-medium text-colorDefault'>{depositValue}</span>
176
+ </div>
177
+ <Divider className='h-px w-full bg-gray-100' />
178
+ </>
179
+ )}
180
+ <div className='flex justify-between items-center text-[13px] text-gray-600 gap-4'>
181
+ <span className='font-medium text-gray-500'>Payment Type:</span>
182
+ <Select
183
+ wrapperClassname='justify-end w-full max-w-[180px]'
184
+ className='w-full text-[13px]'
185
+ options={paymentOptions}
186
+ value={selectedPaymentType}
187
+ onChange={handlePaymentTypeChange}
188
+ showPlaceholder={false}
189
+ />
33
190
  </div>
34
- <Divider className="w-[1px] h-[50px]" />
35
- <div className='flex flex-col gap-2.5'>
36
- <div className='text-[14px] font-medium text-gray-500'>
37
- Last Date
38
- </div>
39
- <div className='text-[16px] font-medium text-colorDefault text-center'>
40
- 31, March 2024
41
- </div>
191
+ <Divider className='h-px w-full bg-gray-100' />
192
+ <div className='flex justify-between text-[13px] text-gray-600'>
193
+ <span className='font-medium text-gray-500'>Pre Order Closing Date:</span>
194
+ <span className='font-medium text-colorDefault'>{formatDate(preOrderClosingDate)}</span>
42
195
  </div>
43
- <Divider className="w-[1px] h-[50px]" />
44
- <div className='flex flex-col gap-2.5'>
45
- <div className='text-[14px] font-medium text-gray-500'>
46
- Deposite
47
- </div>
48
- <div className='text-[16px] font-medium text-colorDefault text-center'>
49
- 40%
50
- </div>
196
+ <Divider className='h-px w-full bg-gray-100' />
197
+ <div className='flex justify-between text-[13px] text-gray-600'>
198
+ <span className='font-medium text-gray-500'>Release Date:</span>
199
+ <span className='font-medium text-colorDefault'>{formatDate(preOrderAvailableDate)}</span>
51
200
  </div>
201
+ <Divider className='h-px w-full bg-gray-100' />
202
+ <div className='flex justify-between text-[13px] text-gray-600'>
203
+ <span className='font-medium text-gray-500'>Note:</span>
204
+ <span className='font-medium text-colorDefault text-right'>
205
+ {preOrderNotes || '-'}
206
+ </span>
207
+ </div>
208
+ {isPreOrderClosed && (
209
+ <div className='mt-1 text-[12px] text-red-500 font-medium'>
210
+ Pre order is closed. You can no longer place a pre-order for this product.
211
+ </div>
212
+ )}
52
213
  </div>
53
- {preOrderNotes && <p>
54
- Notes : {preOrderNotes}
55
- </p>}
56
214
  </div>
57
215
  </>
58
216
  ) : ''