@ikas/storefront 4.0.0-alpha.43 → 4.0.0-alpha.45

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 (35) hide show
  1. package/package.json +11 -11
  2. package/src/components/checkout/components/address-form/model.ts +1 -0
  3. package/src/components/checkout/components/button/style.module.scss +2 -2
  4. package/src/components/checkout/components/cart-summary/cart-item/index.tsx +11 -26
  5. package/src/components/checkout/components/cart-summary/cart-item/style.module.scss +53 -13
  6. package/src/components/checkout/components/cart-summary/index.tsx +23 -16
  7. package/src/components/checkout/components/cart-summary/style.module.scss +48 -3
  8. package/src/components/checkout/components/customer-addresses/index.tsx +1 -0
  9. package/src/components/checkout/components/customer-addresses/model.ts +16 -8
  10. package/src/components/checkout/components/error/index.tsx +1 -1
  11. package/src/components/checkout/components/error/unknown-error/index.tsx +4 -2
  12. package/src/components/checkout/index.tsx +14 -7
  13. package/src/components/checkout/model.ts +126 -37
  14. package/src/components/checkout/steps/step-info/index.tsx +9 -3
  15. package/src/components/checkout/steps/step-payment/billing-address/index.tsx +1 -1
  16. package/src/components/checkout/steps/step-payment/index.tsx +5 -1
  17. package/src/components/checkout/steps/step-success/index.tsx +5 -3
  18. package/src/components/page-editor/ThemeComponentEditor.tsx +4 -0
  19. package/src/models/data/checkout/index.ts +25 -1
  20. package/src/models/data/country/index.ts +4 -0
  21. package/src/models/data/country/location-translations/index.ts +15 -0
  22. package/src/models/data/order/line-item/base-unit/index.ts +22 -0
  23. package/src/models/data/order/line-item/base-unit/unit-type/index.ts +14 -0
  24. package/src/models/data/order/line-item/index.ts +42 -5
  25. package/src/models/data/order/line-item/variant/index.ts +8 -0
  26. package/src/models/data/order/line-item/variant/price/index.ts +2 -0
  27. package/src/models/data/order/line-item/variant/unit/index.ts +17 -0
  28. package/src/models/data/product/attribute-value/index.ts +40 -0
  29. package/src/models/data/product/base-unit/index.ts +19 -0
  30. package/src/models/data/product/index.ts +5 -0
  31. package/src/models/data/product/variant/index.ts +3 -0
  32. package/src/models/data/product/variant/unit/index.ts +17 -0
  33. package/src/models/data/raffle/index.ts +2 -2
  34. package/src/models/data/storefront/routing/index.tsx +4 -0
  35. package/src/models/data/category/init.ts +0 -33
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ikas/storefront",
3
- "version": "4.0.0-alpha.43",
3
+ "version": "4.0.0-alpha.45",
4
4
  "description": "Storefront functionality for ikas storefront themes.",
5
5
  "author": "Umut Ozan Yıldırım",
6
6
  "license": "ISC",
@@ -24,11 +24,11 @@
24
24
  "libphonenumber-js": "^1.10.6"
25
25
  },
26
26
  "devDependencies": {
27
- "@ikas/storefront-api": "^4.0.0-alpha.43",
28
- "@ikas/storefront-config": "^4.0.0-alpha.43",
29
- "@ikas/storefront-model-functions": "^4.0.0-alpha.43",
30
- "@ikas/storefront-models": "^4.0.0-alpha.43",
31
- "@ikas/storefront-providers": "^4.0.0-alpha.43",
27
+ "@ikas/storefront-api": "^4.0.0-alpha.45",
28
+ "@ikas/storefront-config": "^4.0.0-alpha.45",
29
+ "@ikas/storefront-model-functions": "^4.0.0-alpha.45",
30
+ "@ikas/storefront-models": "^4.0.0-alpha.45",
31
+ "@ikas/storefront-providers": "^4.0.0-alpha.45",
32
32
  "@rollup/plugin-commonjs": "^22.0.0",
33
33
  "@rollup/plugin-json": "^4.1.0",
34
34
  "@rollup/plugin-node-resolve": "^13.3.0",
@@ -52,11 +52,11 @@
52
52
  "html-react-parser": "^1.4.0"
53
53
  },
54
54
  "peerDependencies": {
55
- "@ikas/storefront-api": "^4.0.0-alpha.43",
56
- "@ikas/storefront-config": "^4.0.0-alpha.43",
57
- "@ikas/storefront-model-functions": "^4.0.0-alpha.43",
58
- "@ikas/storefront-models": "^4.0.0-alpha.43",
59
- "@ikas/storefront-providers": "^4.0.0-alpha.43",
55
+ "@ikas/storefront-api": "^4.0.0-alpha.45",
56
+ "@ikas/storefront-config": "^4.0.0-alpha.45",
57
+ "@ikas/storefront-model-functions": "^4.0.0-alpha.45",
58
+ "@ikas/storefront-models": "^4.0.0-alpha.45",
59
+ "@ikas/storefront-providers": "^4.0.0-alpha.45",
60
60
  "mobx": "^6.1.3",
61
61
  "mobx-react-lite": "^3.1.5",
62
62
  "next": "12.2.0",
@@ -169,6 +169,7 @@ export default class AddressFormViewModel {
169
169
  id: this.allowedCountryIds?.length
170
170
  ? { in: this.allowedCountryIds }
171
171
  : undefined,
172
+ locale: IkasStorefrontConfig.getCurrentLocale(),
172
173
  });
173
174
  let countries = response.data || [];
174
175
 
@@ -39,7 +39,7 @@
39
39
  }
40
40
 
41
41
  &.FullWidthMobile {
42
- @media only screen and(max-width: $breakpoint) {
42
+ @media only screen and (max-width: $breakpoint) {
43
43
  width: 100%;
44
44
  }
45
45
  }
@@ -100,4 +100,4 @@
100
100
  }
101
101
  }
102
102
 
103
- }
103
+ }
@@ -26,18 +26,6 @@ export const CartItem: React.FC<Props> = observer(
26
26
  const [isOptionsModalVisible, setOptionsModalVisible] =
27
27
  React.useState(false);
28
28
 
29
- const adjustmentAmounts = vm.checkout.orderAdjustments?.map(
30
- (a) =>
31
- a.appliedOrderLines
32
- ?.filter((aol) => aol.orderLineId === cartItem.id)
33
- .reduce((total, current) => total + (current.amount || 0), 0) || 0
34
- );
35
-
36
- const adjustmentTotal = adjustmentAmounts?.reduce(
37
- (total, current) => total + current,
38
- 0
39
- );
40
-
41
29
  const formatDateTheme = (val: string) => {
42
30
  const date = formatDate(new Date(val)).split(" ");
43
31
  date.splice(-1);
@@ -130,12 +118,10 @@ export const CartItem: React.FC<Props> = observer(
130
118
  className={styles.Image}
131
119
  src={cartItem.variant.mainImage?.thumbnailSrc}
132
120
  />
121
+ <div className={styles.QuantityCircle}>{cartItem.quantity}</div>
133
122
  </div>
134
- <div className={styles.Right}>
123
+ <div className={styles.Center}>
135
124
  <div className={styles.Name}>{cartItem.variant.name}</div>
136
- <div className={styles.LightText}>
137
- {`${t("checkout-page:quantity")}: ` + cartItem.quantity}
138
- </div>
139
125
  <div className={styles.LightText}>
140
126
  {cartItem.variant.variantValues
141
127
  ?.map((vv) => vv.variantValueName)
@@ -158,23 +144,22 @@ export const CartItem: React.FC<Props> = observer(
158
144
  onClose={() => setOptionsModalVisible(false)}
159
145
  />
160
146
  )}
147
+ </div>
161
148
 
149
+ <div className={styles.Right}>
162
150
  <div className={styles.Price}>
163
151
  {!!cartItem.overridenPriceWithQuantity && (
164
152
  <span className={styles.GrayPrice}>
165
- {!!adjustmentTotal
166
- ? cartItem.formattedFinalPriceWithQuantity
167
- : cartItem.formattedOverridenPriceWithQuantity}
153
+ {cartItem.formattedOverridenPriceWithQuantity}
168
154
  </span>
169
155
  )}
170
- {!!adjustmentTotal
171
- ? formatCurrency(
172
- cartItem.finalPriceWithQuantity - adjustmentTotal,
173
- currencyCode,
174
- cartItem.currencySymbol
175
- )
176
- : cartItem.formattedFinalPriceWithQuantity}
156
+ {cartItem.formattedFinalPriceWithQuantity}
177
157
  </div>
158
+ {cartItem.unitPriceText && (
159
+ <div className={[styles.LightText, styles.Small].join(" ")}>
160
+ {cartItem.unitPriceText}
161
+ </div>
162
+ )}
178
163
  </div>
179
164
  </div>
180
165
  );
@@ -5,21 +5,47 @@
5
5
  width: 100%;
6
6
  margin-bottom: 24px;
7
7
 
8
+ &:last-child {
9
+ margin-bottom: 0;
10
+ }
11
+
8
12
  .ImageContainer {
9
13
  flex: 0 0 auto;
10
- width: 114px;
14
+ width: 72px;
11
15
  position: relative;
12
16
  margin-right: 16px;
17
+ overflow: visible;
18
+
19
+ @media only screen and (max-width: 375px) {
20
+ width: 56px;
21
+ }
13
22
 
14
23
  .Image {
15
24
  width: 100%;
16
25
  object-fit: contain;
17
26
  border-radius: 8px;
18
27
  }
28
+
29
+ .QuantityCircle {
30
+ width: 20px;
31
+ height: 20px;
32
+ border-radius: 10px;
33
+ background-color: $buttonBgColor;
34
+ color: $buttonTextColor;
35
+ display: flex;
36
+ justify-content: center;
37
+ align-items: center;
38
+ font-size: 12px;
39
+ font-weight: 500;
40
+ position: absolute;
41
+ top: -10px;
42
+ right: -10px;
43
+ }
19
44
  }
20
45
 
21
- .Right {
46
+ .Center {
22
47
  position: relative;
48
+ flex: 1 1 auto;
23
49
 
24
50
  .Name {
25
51
  font-size: 16px;
@@ -35,12 +61,7 @@
35
61
  -webkit-box-orient: vertical;
36
62
  }
37
63
 
38
- .LightText {
39
- font-size: 14px;
40
- color: $secondaryTextColor;
41
- line-height: 20px;
42
- margin-top: 2px;
43
- }
64
+
44
65
 
45
66
  .OptionsText {
46
67
  font-size: 14px;
@@ -56,17 +77,36 @@
56
77
  }
57
78
  }
58
79
 
59
- .Price {
60
- font-size: 14px;
80
+ .Right {
81
+ flex: 0 0 auto;
61
82
  display: flex;
62
- align-items: center;
63
- color: $primaryTextColor;
83
+ flex-direction: column;
84
+ align-items: flex-end;
85
+
86
+ .Price {
87
+ font-size: 14px;
88
+ display: flex;
89
+ flex-direction: column;
90
+ align-items: flex-end;
91
+ color: $primaryTextColor;
92
+ }
64
93
 
65
94
  .GrayPrice {
66
95
  font-size: 14px;
67
96
  color: $secondaryTextColor;
68
97
  text-decoration: line-through;
69
- margin-right: 8px;
98
+ // margin-right: 8px;
99
+ }
100
+ }
101
+
102
+ .LightText {
103
+ font-size: 14px;
104
+ color: $secondaryTextColor;
105
+ line-height: 20px;
106
+ margin-top: 2px;
107
+
108
+ &.Small {
109
+ font-size: 12px;
70
110
  }
71
111
  }
72
112
 
@@ -113,15 +113,16 @@ export const CartSummary: React.FC<Props> = observer(({ vm, allowExpand }) => {
113
113
  <div className={cartSummaryClasses}>
114
114
  <div className={styles.DetailsContainer} style={detailsContainerStyle}>
115
115
  <div className={styles.Details} ref={setDetailsContainer}>
116
- {checkout.items.map((item, index) => (
117
- <div key={index}>
116
+ <div className={styles.ItemsContainer}>
117
+ {checkout.items.map((item, index) => (
118
118
  <CartItem
119
+ key={index}
119
120
  vm={vm}
120
121
  cartItem={item}
121
122
  currencyCode={checkout.currencyCode}
122
123
  />
123
- </div>
124
- ))}
124
+ ))}
125
+ </div>
125
126
  <div className={styles.Divider} />
126
127
  <div className={styles.SubTotalInfo}>
127
128
  {hasCouponError && (
@@ -149,12 +150,7 @@ export const CartSummary: React.FC<Props> = observer(({ vm, allowExpand }) => {
149
150
  }
150
151
  />
151
152
  )}
152
- {!!checkout.totalTax && !!vm.customizationProps?.showTax && (
153
- <InfoRow
154
- label={t("checkout-page:cartTaxTitle")}
155
- value={checkout.formattedTotalTax}
156
- />
157
- )}
153
+
158
154
  {!!vm.installmentExtraPrice && (
159
155
  <InfoRow
160
156
  label={t("checkout-page:cartInterest")}
@@ -194,12 +190,23 @@ export const CartSummary: React.FC<Props> = observer(({ vm, allowExpand }) => {
194
190
  <div className={styles.TitleContainer}>
195
191
  <div className={styles.Title}>{t("checkout-page:total")}</div>
196
192
  </div>
197
- <div className={styles.TotalPrice}>
198
- {formatCurrency(
199
- vm.finalPrice || 0,
200
- checkout.currencyCode,
201
- checkout.currencySymbol
202
- )}
193
+ <div>
194
+ <div className={styles.TotalPricesContainer}>
195
+ <div className={styles.TotalPrice}>
196
+ {formatCurrency(
197
+ vm.finalPrice || 0,
198
+ checkout.currencyCode,
199
+ checkout.currencySymbol
200
+ )}
201
+ </div>
202
+ {!!checkout.$totalTax && !!vm.customizationProps?.showTax && (
203
+ <div className={[styles.TotalTax].join(" ")}>
204
+ {t("checkout-page:cartTaxTitle") +
205
+ " " +
206
+ checkout.$formattedTotalTax}
207
+ </div>
208
+ )}
209
+ </div>
203
210
  </div>
204
211
  </div>
205
212
 
@@ -56,12 +56,45 @@
56
56
  background-color: $cardBgColor;
57
57
  }
58
58
 
59
- .HideOnDesktop {
59
+ &.HideOnDesktop {
60
60
  @media only screen and (min-width: $breakpoint) {
61
61
  display: none;
62
62
  }
63
63
  }
64
64
 
65
+ .ItemsContainer {
66
+ max-height: 320px;
67
+ overflow-y: auto;
68
+ padding-top: 10px;
69
+ margin-bottom: 24px;
70
+
71
+ @media only screen and (max-width: $breakpoint) {
72
+ max-height: unset;
73
+ }
74
+
75
+ &::-webkit-scrollbar {
76
+ width: 10px;
77
+ }
78
+
79
+ /* Track */
80
+ &::-webkit-scrollbar-track {
81
+ box-shadow: inset 0 0 10px 10px #E3E7EF;
82
+ border: solid 3px transparent;
83
+ }
84
+
85
+ /* Handle */
86
+ &::-webkit-scrollbar-thumb {
87
+ box-shadow: inset 0 0 10px 10px #000000;
88
+ border: solid 3px transparent;
89
+ }
90
+
91
+ // /* Handle on hover */
92
+ // &::-webkit-scrollbar-thumb:hover {
93
+ // box-shadow: inset 0 0 10px 10px #000000;
94
+ // border: solid 3px transparent;
95
+ // }
96
+ }
97
+
65
98
  .DetailsContainer {
66
99
  overflow: hidden;
67
100
  width: 100%;
@@ -75,6 +108,7 @@
75
108
 
76
109
  .Details {
77
110
  overflow: hidden;
111
+ padding-top: 10px;
78
112
 
79
113
  @media only screen and (max-width: $breakpoint) {
80
114
  padding-top: $mobileHorizontalPadding;
@@ -141,7 +175,7 @@
141
175
  .TotalContainer {
142
176
  display: flex;
143
177
  justify-content: space-between;
144
- align-items: center;
178
+ // align-items: center;
145
179
  margin-top: 12px;
146
180
 
147
181
  .TitleContainer {
@@ -151,14 +185,25 @@
151
185
  }
152
186
  }
153
187
 
188
+ .TotalPricesContainer {
189
+ display: flex;
190
+ flex-direction: column;
191
+ align-items: flex-end;
192
+ }
193
+
154
194
  .TotalPrice {
155
195
  font-size: 20px;
156
196
  font-weight: 600;
157
197
  }
158
198
 
199
+ .TotalTax {
200
+ font-size: 14px;
201
+ line-height: 24px;
202
+ color: $secondaryTextColor;
203
+ }
204
+
159
205
  @media only screen and (max-width: $breakpoint) {
160
206
  height: 64px;
161
- margin-top: 0px;
162
207
  }
163
208
  }
164
209
 
@@ -87,6 +87,7 @@ const CustomerAddresses: React.FC<Props> = ({ vm }) => {
87
87
  return (
88
88
  <React.Fragment>
89
89
  {!!IkasStorefrontConfig.getPickupStockLocationIds() &&
90
+ !vm.vm.isDigitalOnly &&
90
91
  vm.vm.availableStockLocations.length > 0 &&
91
92
  vm.vm.step !== CheckoutStep.PAYMENT && (
92
93
  <>
@@ -54,9 +54,10 @@ export default class CustomerAddressesViewModel {
54
54
  };
55
55
 
56
56
  onDeleteAddressClick = async () => {
57
- const addressIndex = this.vm.store.customerStore.customer?.addresses?.findIndex(
58
- (a) => a.id === this.editingCustomerAddress?.id
59
- );
57
+ const addressIndex =
58
+ this.vm.store.customerStore.customer?.addresses?.findIndex(
59
+ (a) => a.id === this.editingCustomerAddress?.id
60
+ );
60
61
 
61
62
  if (addressIndex !== -1 && addressIndex !== undefined) {
62
63
  const customer = _cloneDeep(this.vm.store.customerStore.customer)!;
@@ -86,9 +87,10 @@ export default class CustomerAddressesViewModel {
86
87
  return;
87
88
  }
88
89
 
89
- const addressIndex = this.vm.store.customerStore.customer?.addresses?.findIndex(
90
- (a) => a.id === this.editingCustomerAddress?.id
91
- );
90
+ const addressIndex =
91
+ this.vm.store.customerStore.customer?.addresses?.findIndex(
92
+ (a) => a.id === this.editingCustomerAddress?.id
93
+ );
92
94
 
93
95
  if (addressIndex !== -1 && addressIndex !== undefined) {
94
96
  const customer = _cloneDeep(this.vm.store.customerStore.customer)!;
@@ -113,13 +115,19 @@ export default class CustomerAddressesViewModel {
113
115
  };
114
116
 
115
117
  firstNameChangeCallback = (value: string) => {
116
- if (!this.vm.checkout.hasCustomer && this.addressType === "shipping") {
118
+ if (
119
+ (!this.vm.checkout.hasCustomer && this.addressType === "shipping") ||
120
+ this.vm.isDigitalOnly
121
+ ) {
117
122
  this.vm.checkout.customer!.firstName = value;
118
123
  }
119
124
  };
120
125
 
121
126
  lastNameChangeCallback = (value: string) => {
122
- if (!this.vm.checkout.hasCustomer && this.addressType === "shipping") {
127
+ if (
128
+ (!this.vm.checkout.hasCustomer && this.addressType === "shipping") ||
129
+ this.vm.isDigitalOnly
130
+ ) {
123
131
  this.vm.checkout.customer!.lastName = value;
124
132
  }
125
133
  };
@@ -31,7 +31,7 @@ const Errors: React.FC<CommonProps> = ({ vm }) => {
31
31
  break;
32
32
  case ErrorType.API_ERROR:
33
33
  case ErrorType.UNKNOWN:
34
- error = <UnknownError onClose={onErrorClose} />;
34
+ error = <UnknownError error={vm.error} onClose={onErrorClose} />;
35
35
  break;
36
36
 
37
37
  default:
@@ -2,17 +2,19 @@ import * as React from "react";
2
2
  import { observer } from "mobx-react-lite";
3
3
  import NotificationBox from "../../notification-box";
4
4
  import { useTranslation } from "../../../../../utils";
5
+ import { CheckoutError } from "../../../model";
5
6
 
6
7
  type Props = {
8
+ error?: CheckoutError | null;
7
9
  onClose: () => void;
8
10
  };
9
11
 
10
- export const UnknownError: React.FC<Props> = observer(({ onClose }) => {
12
+ export const UnknownError: React.FC<Props> = observer(({ error, onClose }) => {
11
13
  const { t } = useTranslation();
12
14
  return (
13
15
  <NotificationBox
14
16
  type="error"
15
- content={<div>{t("checkout-page:errorUnknown")}</div>}
17
+ content={<div>{error?.data || t("checkout-page:errorUnknown")}</div>}
16
18
  onClose={onClose}
17
19
  />
18
20
  );
@@ -355,7 +355,7 @@ const Steps: React.FC<CommonProps> = observer(({ vm }) => {
355
355
  ),
356
356
  ];
357
357
 
358
- if (vm.deliveryMethod === "address") {
358
+ if (vm.deliveryMethod === "address" && !vm.isDigitalOnly) {
359
359
  steps.splice(
360
360
  1,
361
361
  0,
@@ -393,10 +393,13 @@ const Steps: React.FC<CommonProps> = observer(({ vm }) => {
393
393
  const StepSummaryAddress: React.FC<CommonProps> = observer(({ vm }) => {
394
394
  const { t } = useTranslation();
395
395
 
396
- const customerName =
397
- (vm.checkout.shippingAddress?.firstName || "") +
398
- " " +
399
- (vm.checkout.shippingAddress?.lastName || "");
396
+ const customerName = vm.isDigitalOnly
397
+ ? (vm.checkout.billingAddress?.firstName || "") +
398
+ " " +
399
+ (vm.checkout.billingAddress?.lastName || "")
400
+ : (vm.checkout.shippingAddress?.firstName || "") +
401
+ " " +
402
+ (vm.checkout.shippingAddress?.lastName || "");
400
403
 
401
404
  return (
402
405
  <div className={styles.Address}>
@@ -415,7 +418,9 @@ const StepSummaryAddress: React.FC<CommonProps> = observer(({ vm }) => {
415
418
  )}
416
419
 
417
420
  <div className={[styles.Text, styles.Gray].join(" ")}>
418
- {vm.checkout.shippingAddress?.phone}
421
+ {vm.isDigitalOnly
422
+ ? vm.checkout.billingAddress?.phone
423
+ : vm.checkout.shippingAddress?.phone}
419
424
  </div>
420
425
 
421
426
  {vm.deliveryMethod === "in-store" && (
@@ -426,7 +431,9 @@ const StepSummaryAddress: React.FC<CommonProps> = observer(({ vm }) => {
426
431
  </>
427
432
  )}
428
433
  <div className={[styles.Text, styles.Gray].join(" ")}>
429
- {vm.checkout.shippingAddress?.addressText}
434
+ {vm.isDigitalOnly
435
+ ? vm.checkout.billingAddress?.addressText
436
+ : vm.checkout.shippingAddress?.addressText}
430
437
  </div>
431
438
  </div>
432
439
  );