@ikas/storefront 4.0.0-alpha.5 → 4.0.0-alpha.50
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/package.json +13 -13
- package/src/analytics/analytics.ts +2 -1
- package/src/analytics/googleUniversal.ts +12 -2
- package/src/analytics/head/index.tsx +1 -2
- package/src/analytics/ikas.ts +25 -7
- package/src/components/checkout/components/address-form/index.tsx +1 -1
- package/src/components/checkout/components/address-form/model.ts +1 -0
- package/src/components/checkout/components/button/style.module.scss +2 -2
- package/src/components/checkout/components/cart-summary/cart-item/index.tsx +16 -29
- package/src/components/checkout/components/cart-summary/cart-item/style.module.scss +60 -23
- package/src/components/checkout/components/cart-summary/index.tsx +58 -27
- package/src/components/checkout/components/cart-summary/style.module.scss +48 -3
- package/src/components/checkout/components/customer-addresses/index.tsx +7 -2
- package/src/components/checkout/components/customer-addresses/model.ts +16 -8
- package/src/components/checkout/components/error/index.tsx +1 -1
- package/src/components/checkout/components/error/unknown-error/index.tsx +4 -2
- package/src/components/checkout/components/form-item/index.tsx +9 -11
- package/src/components/checkout/components/master-pass/credit-card-form/index.tsx +2 -0
- package/src/components/checkout/components/offer-product/index.tsx +16 -19
- package/src/components/checkout/components/offer-product/style.module.scss +1 -3
- package/src/components/checkout/components/phone-number-input/get-countries.ts +37 -5
- package/src/components/checkout/components/phone-number-input/index.tsx +15 -10
- package/src/components/checkout/index.tsx +28 -19
- package/src/components/checkout/model.ts +214 -91
- package/src/components/checkout/modelMasterPass.ts +2 -2
- package/src/components/checkout/steps/step-info/index.tsx +9 -3
- package/src/components/checkout/steps/step-payment/billing-address/index.tsx +1 -1
- package/src/components/checkout/steps/step-payment/index.tsx +11 -2
- package/src/components/checkout/steps/step-payment/payment-gateways/index.tsx +12 -3
- package/src/components/checkout/steps/step-payment/payment-gateways/installments/index.tsx +5 -3
- package/src/components/checkout/steps/step-payment/style.module.scss +5 -0
- package/src/components/checkout/steps/step-shipping/index.tsx +9 -4
- package/src/components/checkout/steps/step-success/index.tsx +15 -7
- package/src/components/page/head.tsx +12 -0
- package/src/components/page/index.tsx +10 -9
- package/src/components/page-editor/ThemeComponentEditor.tsx +19 -8
- package/src/components/page-editor/model.ts +44 -107
- package/src/models/data/cart/campaign-offer/index.ts +13 -2
- package/src/models/data/cart/index.ts +1 -1
- package/src/models/data/category/path-item/index.ts +4 -0
- package/src/models/data/checkout/index.ts +36 -4
- package/src/models/data/checkout-settings/price/index.ts +2 -0
- package/src/models/data/country/index.ts +4 -0
- package/src/models/data/country/location-translations/index.ts +15 -0
- package/src/models/data/index.ts +3 -0
- package/src/models/data/merchant-settings/index.ts +9 -0
- package/src/models/data/order/index.ts +51 -32
- package/src/models/data/order/line-item/base-unit/index.ts +22 -0
- package/src/models/data/order/line-item/base-unit/unit-type/index.ts +14 -0
- package/src/models/data/order/line-item/index.ts +76 -18
- package/src/models/data/order/line-item/variant/index.ts +8 -0
- package/src/models/data/order/line-item/variant/price/index.ts +2 -0
- package/src/models/data/order/line-item/variant/unit/index.ts +17 -0
- package/src/models/data/order/line-item/variant/value/index.ts +1 -1
- package/src/models/data/order/transaction/index.ts +2 -5
- package/src/models/data/product/attribute-value/index.ts +40 -0
- package/src/models/data/product/base-unit/index.ts +32 -0
- package/src/models/data/product/filter/index.ts +4 -13
- package/src/models/data/product/index.ts +45 -7
- package/src/models/data/product/option-set/index.ts +8 -3
- package/src/models/data/product/option-set/option/index.ts +36 -13
- package/src/models/data/product/variant/index.ts +26 -1
- package/src/models/data/product/variant/price/index.ts +25 -9
- package/src/models/data/product/variant/unit/index.ts +17 -0
- package/src/models/data/product/variant-type/index.ts +2 -0
- package/src/models/data/raffle/index.ts +9 -7
- package/src/models/data/state/index.ts +6 -2
- package/src/models/data/storefront/index.ts +2 -0
- package/src/models/data/storefront/routing/index.tsx +4 -0
- package/src/models/ui/product-list/index.ts +26 -17
- package/src/models/ui/raffle-list/index.ts +1 -1
- package/src/models/ui/validator/form/raffle-form.ts +16 -3
- package/src/models/ui/validator/rules/index.ts +14 -13
- package/src/page-data-init/index.ts +159 -404
- package/src/pages/checkout.tsx +2 -1
- package/src/pages/editor.tsx +5 -2
- package/src/store/base.ts +2 -2
- package/src/store/cart/index.ts +2 -2
- package/src/store/customer/index.ts +7 -17
- package/src/store/index.ts +2 -0
- package/src/store/raffle/index.ts +7 -10
- package/src/utils/constants.ts +1 -1
- package/src/utils/currency.ts +9 -183
- package/src/components/checkout/components/phone-number-input/locale/en.ts +0 -257
- package/src/models/data/category/init.ts +0 -33
|
@@ -56,12 +56,45 @@
|
|
|
56
56
|
background-color: $cardBgColor;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
|
|
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
|
<>
|
|
@@ -143,7 +144,9 @@ const CustomerAddresses: React.FC<Props> = ({ vm }) => {
|
|
|
143
144
|
|
|
144
145
|
{!!vm.vm.store.customerStore.customer &&
|
|
145
146
|
!vm.editingCustomerAddress &&
|
|
146
|
-
vm.vm.deliveryMethod === "address"
|
|
147
|
+
(vm.vm.deliveryMethod === "address" ||
|
|
148
|
+
(vm.vm.step === CheckoutStep.PAYMENT &&
|
|
149
|
+
vm.vm.deliveryMethod === "in-store")) && (
|
|
147
150
|
<div className={checkoutStyles.RowPB}>
|
|
148
151
|
{vm.vm.store.customerStore.customer.addresses?.map((address) => (
|
|
149
152
|
<SelectBox
|
|
@@ -183,7 +186,9 @@ const CustomerAddresses: React.FC<Props> = ({ vm }) => {
|
|
|
183
186
|
vm.vm.step === CheckoutStep.INFO &&
|
|
184
187
|
vm.vm.deliveryMethod === "address"
|
|
185
188
|
? addressForm
|
|
186
|
-
: vm.vm.step === CheckoutStep.PAYMENT &&
|
|
189
|
+
: vm.vm.step === CheckoutStep.PAYMENT &&
|
|
190
|
+
!vm.vm.store.customerStore.customer &&
|
|
191
|
+
addressForm}
|
|
187
192
|
|
|
188
193
|
{vm.vm.deliveryMethod === "in-store" && (
|
|
189
194
|
<div className={checkoutStyles.RowPB}>
|
|
@@ -54,9 +54,10 @@ export default class CustomerAddressesViewModel {
|
|
|
54
54
|
};
|
|
55
55
|
|
|
56
56
|
onDeleteAddressClick = async () => {
|
|
57
|
-
const addressIndex =
|
|
58
|
-
|
|
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 =
|
|
90
|
-
|
|
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 (
|
|
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 (
|
|
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
|
);
|
|
@@ -7,6 +7,7 @@ import styles from "./style.module.scss";
|
|
|
7
7
|
|
|
8
8
|
import { useTranslation } from "../../../../utils";
|
|
9
9
|
import ReactTooltip from "react-tooltip";
|
|
10
|
+
import { PhoneNumberInput } from "../phone-number-input";
|
|
10
11
|
|
|
11
12
|
export const FormItem: React.FC<Props> = observer((props) => {
|
|
12
13
|
const { t } = useTranslation();
|
|
@@ -108,17 +109,14 @@ export const FormItem: React.FC<Props> = observer((props) => {
|
|
|
108
109
|
/>
|
|
109
110
|
)}
|
|
110
111
|
{vm.type === FormItemType.TEL && (
|
|
111
|
-
<
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
// international={true}
|
|
120
|
-
// addInternationalOption={false}
|
|
121
|
-
// />
|
|
112
|
+
<PhoneNumberInput
|
|
113
|
+
key={props.currentCountryCode || "1"}
|
|
114
|
+
disabled={vm.disabled}
|
|
115
|
+
defaultCountry={props.currentCountryCode}
|
|
116
|
+
placeholder={t("checkout-page:enterPhoneNumber")}
|
|
117
|
+
value={vm.value ? vm.value : ""}
|
|
118
|
+
onChange={vm.onPhoneChange}
|
|
119
|
+
/>
|
|
122
120
|
)}
|
|
123
121
|
{vm.type === FormItemType.TEXT_AREA && <TextArea vm={vm} />}
|
|
124
122
|
{vm.type === FormItemType.SELECT && (
|
|
@@ -132,7 +132,9 @@ const CreditCardFormMasterPass = observer(({ vm }: Props) => {
|
|
|
132
132
|
<div className={checkoutStyles.RowPB}>
|
|
133
133
|
<FormItem
|
|
134
134
|
name="masterPassPhoneNumber"
|
|
135
|
+
autocomplete="tel"
|
|
135
136
|
type={FormItemType.TEL}
|
|
137
|
+
currentCountryCode={vm.store.currentCountryCode}
|
|
136
138
|
disabled={
|
|
137
139
|
vm.mpVM.isSaveCardToMasterPassPhoneNumberInputDisabled
|
|
138
140
|
}
|
|
@@ -8,7 +8,7 @@ import SVGCross from "../svg/cross";
|
|
|
8
8
|
import styles from "./style.module.scss";
|
|
9
9
|
import { useTranslation } from "../../../../utils/i18n";
|
|
10
10
|
import { IkasProductVariant } from "../../../../models";
|
|
11
|
-
import {
|
|
11
|
+
import { formatCurrency } from "../../../../utils/currency";
|
|
12
12
|
|
|
13
13
|
type Props = {
|
|
14
14
|
vm: CheckoutViewModel;
|
|
@@ -18,7 +18,7 @@ type Props = {
|
|
|
18
18
|
const OfferProduct: React.FC<Props> = ({ vm, campaignOffer }) => {
|
|
19
19
|
const { t } = useTranslation();
|
|
20
20
|
const [selectedVariant, setSelectedVariant] =
|
|
21
|
-
React.useState<IkasProductVariant>(campaignOffer
|
|
21
|
+
React.useState<IkasProductVariant>(campaignOffer.variants[0]);
|
|
22
22
|
|
|
23
23
|
const acceptOffer = () => {
|
|
24
24
|
vm.updateCartCampaignOffer({
|
|
@@ -43,7 +43,7 @@ const OfferProduct: React.FC<Props> = ({ vm, campaignOffer }) => {
|
|
|
43
43
|
};
|
|
44
44
|
|
|
45
45
|
const onVariantChange = (value: string) => {
|
|
46
|
-
const variant = campaignOffer.
|
|
46
|
+
const variant = campaignOffer.variants.find((v) => v.id === value);
|
|
47
47
|
|
|
48
48
|
if (variant) {
|
|
49
49
|
setSelectedVariant(variant);
|
|
@@ -95,35 +95,32 @@ const OfferProduct: React.FC<Props> = ({ vm, campaignOffer }) => {
|
|
|
95
95
|
<span className={styles.Discount}>
|
|
96
96
|
{selectedVariant.price.formattedFinalPrice}
|
|
97
97
|
</span>{" "}
|
|
98
|
-
{
|
|
98
|
+
{formatCurrency(
|
|
99
99
|
selectedVariant.price.finalPrice -
|
|
100
100
|
(selectedVariant.price.finalPrice *
|
|
101
101
|
(campaignOffer.offer.discountAmount || 100)) /
|
|
102
102
|
100,
|
|
103
|
-
vm.checkout!.currencyCode
|
|
103
|
+
vm.checkout!.currencyCode,
|
|
104
|
+
vm.checkout!.currencySymbol
|
|
104
105
|
)}
|
|
105
106
|
</div>
|
|
106
107
|
<div className={styles.Actions}>
|
|
107
|
-
{campaignOffer.
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}))}
|
|
118
|
-
/>
|
|
119
|
-
)}
|
|
108
|
+
{campaignOffer.variants.length > 1 && (
|
|
109
|
+
<Select
|
|
110
|
+
value={selectedVariant.id}
|
|
111
|
+
onSelectChange={onVariantChange}
|
|
112
|
+
options={campaignOffer.variants.map((v) => ({
|
|
113
|
+
label: v.variantValues.map((vv) => vv.name).join(", "),
|
|
114
|
+
value: v.id,
|
|
115
|
+
}))}
|
|
116
|
+
/>
|
|
117
|
+
)}
|
|
120
118
|
<Button
|
|
121
119
|
style={{
|
|
122
120
|
width: "100%",
|
|
123
121
|
height: 44,
|
|
124
122
|
fontSize: 14,
|
|
125
123
|
}}
|
|
126
|
-
isDisabled={!campaignOffer.product.hasStock}
|
|
127
124
|
text={t("checkout-page:actions.addToCart")}
|
|
128
125
|
onClick={acceptOffer}
|
|
129
126
|
/>
|
|
@@ -62,7 +62,6 @@
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
.ImageContainer {
|
|
65
|
-
height: 136px;
|
|
66
65
|
width: 136px;
|
|
67
66
|
position: relative;
|
|
68
67
|
background-color: #fff;
|
|
@@ -73,8 +72,7 @@
|
|
|
73
72
|
|
|
74
73
|
.Image {
|
|
75
74
|
width: 100%;
|
|
76
|
-
|
|
77
|
-
object-fit: cover;
|
|
75
|
+
object-fit: contain;
|
|
78
76
|
border-radius: 8px;
|
|
79
77
|
}
|
|
80
78
|
|
|
@@ -1,18 +1,50 @@
|
|
|
1
|
+
import { IkasStorefrontConfig } from "@ikas/storefront-config";
|
|
1
2
|
import { CountryCode, getCountries as categories } from "libphonenumber-js";
|
|
2
3
|
import compareStrings from "./compare-strings";
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
type CountryType = {
|
|
5
|
+
export type CountryType = {
|
|
7
6
|
value: CountryCode;
|
|
8
7
|
label: string | undefined;
|
|
9
8
|
};
|
|
10
9
|
|
|
11
|
-
const
|
|
10
|
+
const getUrl = () => {
|
|
11
|
+
const languages = [
|
|
12
|
+
"de",
|
|
13
|
+
"el",
|
|
14
|
+
"en",
|
|
15
|
+
"es",
|
|
16
|
+
"fi",
|
|
17
|
+
"fr",
|
|
18
|
+
"it",
|
|
19
|
+
"nb",
|
|
20
|
+
"pl",
|
|
21
|
+
"pt-BR",
|
|
22
|
+
"pt",
|
|
23
|
+
"ru",
|
|
24
|
+
"sv",
|
|
25
|
+
"tr",
|
|
26
|
+
"ua",
|
|
27
|
+
"vi",
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
let locale = IkasStorefrontConfig.getCurrentLocale();
|
|
31
|
+
|
|
32
|
+
if (!languages.some((language) => language === locale)) {
|
|
33
|
+
locale = "en";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return `https://cdn.myikas.com/sf/static/locale/country/${locale}.json`;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const getCountries = async (): Promise<CountryType[]> => {
|
|
40
|
+
const url = getUrl();
|
|
41
|
+
const response = await fetch(url);
|
|
42
|
+
const lang = await response.json();
|
|
43
|
+
|
|
12
44
|
return categories()
|
|
13
45
|
.map((country) => ({
|
|
14
46
|
value: country,
|
|
15
|
-
label:
|
|
47
|
+
label: lang[country],
|
|
16
48
|
}))
|
|
17
49
|
.sort((a, b) => compareStrings(a.label, b.label));
|
|
18
50
|
};
|
|
@@ -6,8 +6,7 @@ import parsePhoneNumber, {
|
|
|
6
6
|
getCountryCallingCode,
|
|
7
7
|
parseIncompletePhoneNumber,
|
|
8
8
|
} from "libphonenumber-js";
|
|
9
|
-
|
|
10
|
-
import getCountries from "./get-countries";
|
|
9
|
+
import getCountries, { CountryType } from "./get-countries";
|
|
11
10
|
|
|
12
11
|
import styles from "./style.module.scss";
|
|
13
12
|
|
|
@@ -19,17 +18,20 @@ type Props = {
|
|
|
19
18
|
onChange: (value: string) => void;
|
|
20
19
|
};
|
|
21
20
|
|
|
22
|
-
const
|
|
21
|
+
const DEFAULT_COUNTRY = "TR";
|
|
23
22
|
|
|
24
23
|
export const PhoneNumberInput: React.FC<Props> = observer(
|
|
25
24
|
({ defaultCountry, disabled = false, placeholder, value, onChange }) => {
|
|
25
|
+
const [countries, setCountries] = React.useState<CountryType[]>([]);
|
|
26
26
|
const [activeCountry, setActiveCountry] = React.useState(
|
|
27
|
-
defaultCountry as CountryCode
|
|
27
|
+
(defaultCountry as CountryCode) || DEFAULT_COUNTRY
|
|
28
28
|
);
|
|
29
29
|
const [formatedValue, setFormatedValue] = React.useState("");
|
|
30
30
|
|
|
31
31
|
React.useEffect(() => {
|
|
32
|
-
|
|
32
|
+
fetchCountries();
|
|
33
|
+
|
|
34
|
+
let countryCode = activeCountry;
|
|
33
35
|
|
|
34
36
|
if (value) {
|
|
35
37
|
const parsedPhoneNumber = parsePhoneNumber(value);
|
|
@@ -46,6 +48,11 @@ export const PhoneNumberInput: React.FC<Props> = observer(
|
|
|
46
48
|
setActiveCountry(countryCode);
|
|
47
49
|
}, []);
|
|
48
50
|
|
|
51
|
+
const fetchCountries = async () => {
|
|
52
|
+
const categories = await getCountries();
|
|
53
|
+
setCountries(categories);
|
|
54
|
+
};
|
|
55
|
+
|
|
49
56
|
const onValueChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
50
57
|
const phoneNumber = formatPhoneNumber(event.target.value);
|
|
51
58
|
setFormatedValue(phoneNumber);
|
|
@@ -76,9 +83,7 @@ export const PhoneNumberInput: React.FC<Props> = observer(
|
|
|
76
83
|
};
|
|
77
84
|
|
|
78
85
|
const getImageSrc = () => {
|
|
79
|
-
return `https://cdn.myikas.com/sf/assets/flags/3x2/${
|
|
80
|
-
activeCountry || "TR"
|
|
81
|
-
}.svg`;
|
|
86
|
+
return `https://cdn.myikas.com/sf/assets/flags/3x2/${activeCountry}.svg`;
|
|
82
87
|
};
|
|
83
88
|
|
|
84
89
|
return (
|
|
@@ -88,14 +93,14 @@ export const PhoneNumberInput: React.FC<Props> = observer(
|
|
|
88
93
|
<div className={styles.Flag}>
|
|
89
94
|
<img
|
|
90
95
|
className={styles.FlagImage}
|
|
91
|
-
alt={activeCountry
|
|
96
|
+
alt={activeCountry}
|
|
92
97
|
src={getImageSrc()}
|
|
93
98
|
></img>
|
|
94
99
|
<div className={styles.Arrow}></div>
|
|
95
100
|
</div>
|
|
96
101
|
<select
|
|
97
102
|
className={styles.Select}
|
|
98
|
-
value={activeCountry
|
|
103
|
+
value={activeCountry}
|
|
99
104
|
onChange={onCountryChange}
|
|
100
105
|
disabled={disabled}
|
|
101
106
|
>
|
|
@@ -7,7 +7,7 @@ import ReactTooltip from "react-tooltip";
|
|
|
7
7
|
import CheckoutViewModel, { CheckoutStep } from "./model";
|
|
8
8
|
import { IkasCheckoutSettings } from "../../models/data/checkout-settings";
|
|
9
9
|
import { IkasCheckout } from "../../models/data/checkout";
|
|
10
|
-
import {
|
|
10
|
+
import { formatCurrency, useTranslation } from "../../utils";
|
|
11
11
|
|
|
12
12
|
import CheckoutStepInfo from "./steps/step-info";
|
|
13
13
|
import { CheckoutStepShipping } from "./steps/step-shipping";
|
|
@@ -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,
|
|
@@ -366,15 +366,16 @@ const Steps: React.FC<CommonProps> = observer(({ vm }) => {
|
|
|
366
366
|
vm.step === CheckoutStep.PAYMENT ? (
|
|
367
367
|
<div className={styles.AdressStepInfo}>
|
|
368
368
|
<StepSummaryShipping vm={vm} />
|
|
369
|
-
{vm.checkout.availableShippingMethods &&
|
|
370
|
-
vm.checkout.availableShippingMethods.length > 1
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
369
|
+
{((vm.checkout.availableShippingMethods &&
|
|
370
|
+
vm.checkout.availableShippingMethods.length > 1) ||
|
|
371
|
+
vm.checkoutSettings.isGiftPackageEnabled) && (
|
|
372
|
+
<div
|
|
373
|
+
className={styles.EditBtn}
|
|
374
|
+
onClick={vm.onBackToShippingClick}
|
|
375
|
+
>
|
|
376
|
+
{t("checkout-page:actions.edit")}
|
|
377
|
+
</div>
|
|
378
|
+
)}
|
|
378
379
|
</div>
|
|
379
380
|
) : undefined,
|
|
380
381
|
vm.step === CheckoutStep.PAYMENT ? (
|
|
@@ -392,10 +393,13 @@ const Steps: React.FC<CommonProps> = observer(({ vm }) => {
|
|
|
392
393
|
const StepSummaryAddress: React.FC<CommonProps> = observer(({ vm }) => {
|
|
393
394
|
const { t } = useTranslation();
|
|
394
395
|
|
|
395
|
-
const customerName =
|
|
396
|
-
(vm.checkout.
|
|
397
|
-
|
|
398
|
-
|
|
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 || "");
|
|
399
403
|
|
|
400
404
|
return (
|
|
401
405
|
<div className={styles.Address}>
|
|
@@ -414,7 +418,9 @@ const StepSummaryAddress: React.FC<CommonProps> = observer(({ vm }) => {
|
|
|
414
418
|
)}
|
|
415
419
|
|
|
416
420
|
<div className={[styles.Text, styles.Gray].join(" ")}>
|
|
417
|
-
{vm.
|
|
421
|
+
{vm.isDigitalOnly
|
|
422
|
+
? vm.checkout.billingAddress?.phone
|
|
423
|
+
: vm.checkout.shippingAddress?.phone}
|
|
418
424
|
</div>
|
|
419
425
|
|
|
420
426
|
{vm.deliveryMethod === "in-store" && (
|
|
@@ -425,7 +431,9 @@ const StepSummaryAddress: React.FC<CommonProps> = observer(({ vm }) => {
|
|
|
425
431
|
</>
|
|
426
432
|
)}
|
|
427
433
|
<div className={[styles.Text, styles.Gray].join(" ")}>
|
|
428
|
-
{vm.
|
|
434
|
+
{vm.isDigitalOnly
|
|
435
|
+
? vm.checkout.billingAddress?.addressText
|
|
436
|
+
: vm.checkout.shippingAddress?.addressText}
|
|
429
437
|
</div>
|
|
430
438
|
</div>
|
|
431
439
|
);
|
|
@@ -443,9 +451,10 @@ const StepSummaryShipping: React.FC<CommonProps> = observer(({ vm }) => {
|
|
|
443
451
|
{" / " +
|
|
444
452
|
(vm.checkout.shippingLines[0].price === 0
|
|
445
453
|
? t("checkout-page:free")
|
|
446
|
-
:
|
|
454
|
+
: formatCurrency(
|
|
447
455
|
vm.checkout.shippingLines[0].price,
|
|
448
|
-
vm.checkout!.currencyCode
|
|
456
|
+
vm.checkout!.currencyCode,
|
|
457
|
+
vm.checkout.currencySymbol
|
|
449
458
|
))}
|
|
450
459
|
</span>
|
|
451
460
|
</React.Fragment>
|