@lookiero/checkout 1.1.1 → 1.1.2
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/README.md +2 -0
- package/dist/infrastructure/projection/bookedProductsVariants/react/useViewBookedProductsVariantsForCheckoutItem.d.ts +1 -1
- package/dist/infrastructure/projection/checkout/react/useViewIsSizeChangeEnabledByCheckoutId.d.ts +1 -1
- package/dist/infrastructure/projection/checkout/react/useViewIsSizeChangeEnabledByCheckoutId.js +2 -1
- package/dist/infrastructure/ui/routing/CheckoutMiddleware.js +3 -0
- package/dist/infrastructure/ui/views/checkout/Checkout.js +1 -1
- package/dist/infrastructure/ui/views/item/Item.d.ts +0 -1
- package/dist/infrastructure/ui/views/item/Item.js +51 -130
- package/dist/infrastructure/ui/views/item/components/banner/CustomerDecissionBanner.js +1 -1
- package/dist/infrastructure/ui/views/item/components/itemActions/ItemActions.d.ts +1 -4
- package/dist/infrastructure/ui/views/item/components/itemActions/ItemActions.js +7 -7
- package/dist/infrastructure/ui/views/item/components/returnQuestionsFeedback/ReturnQuestionsFeedback.js +1 -1
- package/dist/infrastructure/ui/views/item/components/returnQuestionsForm/ReturnQuestionsForm.js +2 -2
- package/dist/infrastructure/ui/views/item/views/itemWithCustomerDecission/ItemWithCustomerDecission.d.ts +18 -0
- package/dist/infrastructure/ui/views/item/views/itemWithCustomerDecission/ItemWithCustomerDecission.js +48 -0
- package/dist/infrastructure/ui/views/item/views/itemWithCustomerDecission/ItemWithCustomerDecission.style.d.ts +8 -0
- package/dist/infrastructure/ui/views/item/{Item.style.js → views/itemWithCustomerDecission/ItemWithCustomerDecission.style.js} +1 -8
- package/dist/infrastructure/ui/views/item/views/itemWithoutCustomerDecission/ItemWithoutCustomerDecission.d.ts +19 -0
- package/dist/infrastructure/ui/views/item/views/itemWithoutCustomerDecission/ItemWithoutCustomerDecission.js +68 -0
- package/dist/infrastructure/ui/views/item/views/productVariant/ProductVariant.d.ts +16 -0
- package/dist/infrastructure/ui/views/item/views/productVariant/ProductVariant.js +28 -0
- package/dist/infrastructure/ui/views/item/{Item.style.d.ts → views/productVariant/ProductVariant.style.d.ts} +0 -5
- package/dist/infrastructure/ui/views/item/views/productVariant/ProductVariant.style.js +13 -0
- package/dist/infrastructure/ui/views/navigation/Navigation.js +4 -4
- package/dist/infrastructure/ui/views/navigation/components/header/Header.d.ts +2 -2
- package/dist/infrastructure/ui/views/navigation/components/header/Header.js +2 -2
- package/dist/infrastructure/ui/views/summary/components/checkoutItemsTabs/CheckoutItemsTabs.js +1 -1
- package/dist/shared/tracking/infrastructure/useTrackPressMenu.d.ts +1 -1
- package/dist/shared/tracking/infrastructure/useTrackPressMenu.js +2 -2
- package/dist/shared/tracking/tracking.d.ts +1 -1
- package/dist/shared/ui/components/atoms/spinner/Spinner.js +1 -1
- package/dist/shared/ui/components/molecules/selectField/SelectField.js +1 -1
- package/package.json +2 -2
- /package/dist/infrastructure/ui/views/{item → shared}/components/productVariant/ProductVariant.d.ts +0 -0
- /package/dist/infrastructure/ui/views/{item → shared}/components/productVariant/ProductVariant.js +0 -0
- /package/dist/infrastructure/ui/views/{item → shared}/components/productVariant/ProductVariant.style.d.ts +0 -0
- /package/dist/infrastructure/ui/views/{item → shared}/components/productVariant/ProductVariant.style.js +0 -0
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ interface UseViewBookedProductsVariantsForCheckoutItemFunctionArgs {
|
|
|
4
4
|
readonly checkoutItemId: string;
|
|
5
5
|
}
|
|
6
6
|
interface UseViewBookedProductsVariantsForCheckoutItemFunction {
|
|
7
|
-
(args: UseViewBookedProductsVariantsForCheckoutItemFunctionArgs): UseQueryFunctionResult<BookedProductsVariantsProjection>;
|
|
7
|
+
(args: UseViewBookedProductsVariantsForCheckoutItemFunctionArgs): UseQueryFunctionResult<BookedProductsVariantsProjection | null>;
|
|
8
8
|
}
|
|
9
9
|
declare const useViewBookedProductsVariantsForCheckoutItem: UseViewBookedProductsVariantsForCheckoutItemFunction;
|
|
10
10
|
export { useViewBookedProductsVariantsForCheckoutItem };
|
package/dist/infrastructure/projection/checkout/react/useViewIsSizeChangeEnabledByCheckoutId.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { UseQueryFunctionResult } from "@lookiero/messaging-react";
|
|
2
2
|
import { IsSizeChangeEnabledByCheckoutIdProjection } from "../../../../projection/checkout/viewIsSizeChangeEnabledByCheckoutId";
|
|
3
3
|
interface UseViewIsSizeChangeEnabledByCheckoutIdFunctionArgs {
|
|
4
|
-
readonly checkoutId: string;
|
|
4
|
+
readonly checkoutId: string | undefined;
|
|
5
5
|
}
|
|
6
6
|
interface UseViewIsSizeChangeEnabledByCheckoutIdFunction {
|
|
7
7
|
(args: UseViewIsSizeChangeEnabledByCheckoutIdFunctionArgs): UseQueryFunctionResult<IsSizeChangeEnabledByCheckoutIdProjection>;
|
package/dist/infrastructure/projection/checkout/react/useViewIsSizeChangeEnabledByCheckoutId.js
CHANGED
|
@@ -2,12 +2,13 @@ import { useQuery } from "@lookiero/messaging-react";
|
|
|
2
2
|
import { viewIsSizeChangeEnabledByCheckoutId, } from "../../../../projection/checkout/viewIsSizeChangeEnabledByCheckoutId";
|
|
3
3
|
import { MESSAGING_CONTEXT_ID } from "../../../delivery/baseBootstrap";
|
|
4
4
|
const useViewIsSizeChangeEnabledByCheckoutId = ({ checkoutId }) => useQuery({
|
|
5
|
-
query: viewIsSizeChangeEnabledByCheckoutId({ checkoutId }),
|
|
5
|
+
query: viewIsSizeChangeEnabledByCheckoutId({ checkoutId: checkoutId }),
|
|
6
6
|
contextId: MESSAGING_CONTEXT_ID,
|
|
7
7
|
options: {
|
|
8
8
|
staleTime: Infinity,
|
|
9
9
|
retry: false,
|
|
10
10
|
refetchOnWindowFocus: false,
|
|
11
|
+
enabled: Boolean(checkoutId),
|
|
11
12
|
},
|
|
12
13
|
});
|
|
13
14
|
export { useViewIsSizeChangeEnabledByCheckoutId };
|
|
@@ -6,6 +6,7 @@ import { useLogger } from "../../../shared/logging/useLogger";
|
|
|
6
6
|
import { Spinner } from "../../../shared/ui/components/atoms/spinner/Spinner";
|
|
7
7
|
import { useStartCheckout } from "../../domain/checkout/react/useStartCheckout";
|
|
8
8
|
import { useViewFirstAvailableCheckoutByCustomerId } from "../../projection/checkout/react/useViewFirstAvailableCheckoutByCustomerId";
|
|
9
|
+
import { useViewIsSizeChangeEnabledByCheckoutId } from "../../projection/checkout/react/useViewIsSizeChangeEnabledByCheckoutId";
|
|
9
10
|
import { Routes } from "./routes";
|
|
10
11
|
import { useBasePath } from "./useBasePath";
|
|
11
12
|
const CheckoutMiddleware = ({ customerId, loader = React.createElement(Spinner, null), children }) => {
|
|
@@ -36,6 +37,8 @@ const CheckoutMiddleware = ({ customerId, loader = React.createElement(Spinner,
|
|
|
36
37
|
checkoutShown.current = checkoutShown.current || (Boolean(checkoutRouteMatch) && !Boolean(checkoutPaymentRouteMatch));
|
|
37
38
|
const [checkout] = useViewFirstAvailableCheckoutByCustomerId({ customerId });
|
|
38
39
|
const checkoutItemsRef = useRef();
|
|
40
|
+
/* This hook is mounted at this level, although not being used directly, for optimization (regarding cache) */
|
|
41
|
+
useViewIsSizeChangeEnabledByCheckoutId({ checkoutId: checkout?.id });
|
|
39
42
|
const [startCheckout] = useStartCheckout({ checkoutId: checkout?.id, logger });
|
|
40
43
|
useEffect(() => {
|
|
41
44
|
if (checkout?.id) {
|
|
@@ -16,8 +16,8 @@ import { SafeAreaScrollView } from "../../components/templates/SafeAreaScrollVie
|
|
|
16
16
|
import { I18nMessages } from "../../i18n/i18n";
|
|
17
17
|
import { Routes } from "../../routing/routes";
|
|
18
18
|
import { useBasePath } from "../../routing/useBasePath";
|
|
19
|
-
import { ProductVariant } from "../item/components/productVariant/ProductVariant";
|
|
20
19
|
import { HEADER_HEIGHT } from "../navigation/components/header/Header.style";
|
|
20
|
+
import { ProductVariant } from "../shared/components/productVariant/ProductVariant";
|
|
21
21
|
import { Pricing } from "../summary/components/pricing/Pricing";
|
|
22
22
|
import { style } from "./Checkout.style";
|
|
23
23
|
import { DeliveryBanner } from "./components/deliveryBanner/DeliveryBanner";
|
|
@@ -1,82 +1,60 @@
|
|
|
1
1
|
import { CommandStatus, QueryStatus } from "@lookiero/messaging-react";
|
|
2
|
-
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
|
3
|
-
import { Platform, View } from "react-native";
|
|
2
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
4
3
|
import { useParams } from "react-router-native";
|
|
5
4
|
import { CheckoutItemStatus } from "../../../../domain/checkoutItem/model/checkoutItem";
|
|
6
|
-
import "../../../../projection/checkout/viewFirstAvailableCheckoutByCustomerId";
|
|
7
5
|
import { useLogger } from "../../../../shared/logging/useLogger";
|
|
8
|
-
import { useTrackImageView } from "../../../../shared/tracking/infrastructure/useTrackImageView";
|
|
9
6
|
import { useTrackItemPageView } from "../../../../shared/tracking/infrastructure/useTrackItemPageView";
|
|
10
|
-
import { useTrackKeepItem } from "../../../../shared/tracking/infrastructure/useTrackKeepItem";
|
|
11
|
-
import { useTrackReplaceItem } from "../../../../shared/tracking/infrastructure/useTrackReplaceItem";
|
|
12
|
-
import { useTrackResetItem } from "../../../../shared/tracking/infrastructure/useTrackResetItem";
|
|
13
7
|
import { useTrackReturnItem } from "../../../../shared/tracking/infrastructure/useTrackReturnItem";
|
|
14
8
|
import { Spinner } from "../../../../shared/ui/components/atoms/spinner/Spinner";
|
|
15
9
|
import { useBookCheckoutBookingForCheckoutItem } from "../../../domain/checkoutBooking/react/useBookCheckoutBookingForCheckoutItem";
|
|
16
|
-
import { useKeepCheckoutItem } from "../../../domain/checkoutItem/react/useKeepCheckoutItem";
|
|
17
|
-
import { useReplaceCheckoutItem } from "../../../domain/checkoutItem/react/useReplaceCheckoutItem";
|
|
18
|
-
import { useResetCheckoutItem } from "../../../domain/checkoutItem/react/useResetCheckoutItem";
|
|
19
10
|
import { useReturnCheckoutItem } from "../../../domain/checkoutItem/react/useReturnCheckoutItem";
|
|
20
11
|
import { useViewBookedProductsVariantsForCheckoutItem } from "../../../projection/bookedProductsVariants/react/useViewBookedProductsVariantsForCheckoutItem";
|
|
21
12
|
import { useViewFirstAvailableCheckoutByCustomerId } from "../../../projection/checkout/react/useViewFirstAvailableCheckoutByCustomerId";
|
|
22
13
|
import { useViewIsSizeChangeEnabledByCheckoutId } from "../../../projection/checkout/react/useViewIsSizeChangeEnabledByCheckoutId";
|
|
23
14
|
import { useListReturnQuestionsByCheckoutItemId } from "../../../projection/returnQuestion/react/useListReturnQuestionsByCheckoutItemId";
|
|
24
15
|
import { TrackingPage } from "../../../tracking/tracking";
|
|
25
|
-
import { Body } from "../../components/layouts/body/Body";
|
|
26
16
|
import { ReturnQuestionFeedbackProvider } from "../../components/organisms/returnQuestions/behaviors/useReturnQuestionFeedback";
|
|
27
|
-
import { SafeAreaScrollView } from "../../components/templates/SafeAreaScrollView";
|
|
28
|
-
import { theme } from "../../theme/theme";
|
|
29
|
-
import { HEADER_HEIGHT } from "../navigation/components/header/Header.style";
|
|
30
|
-
import { style } from "./Item.style";
|
|
31
|
-
import { CustomerDecissionBanner } from "./components/banner/CustomerDecissionBanner";
|
|
32
|
-
import { ItemActions } from "./components/itemActions/ItemActions";
|
|
33
|
-
import { ProductVariantDescription } from "./components/productVariantDescription/ProductVariantDescription";
|
|
34
|
-
import { ProductVariantSlider } from "./components/productVariantSlider/ProductVariantSlider";
|
|
35
|
-
import { ReturnQuestionsFeedback } from "./components/returnQuestionsFeedback/ReturnQuestionsFeedback";
|
|
36
17
|
import { ReturnQuestionsForm } from "./components/returnQuestionsForm/ReturnQuestionsForm";
|
|
37
|
-
import {
|
|
38
|
-
|
|
18
|
+
import { ItemWithCustomerDecission, } from "./views/itemWithCustomerDecission/ItemWithCustomerDecission";
|
|
19
|
+
import { ItemWithoutCustomerDecission, } from "./views/itemWithoutCustomerDecission/ItemWithoutCustomerDecission";
|
|
39
20
|
const Item = ({ customerId, country }) => {
|
|
40
21
|
const logger = useLogger();
|
|
41
22
|
const { id } = useParams();
|
|
42
23
|
const [checkout, checkoutStatus] = useViewFirstAvailableCheckoutByCustomerId({ customerId });
|
|
24
|
+
const checkoutItem = checkout?.items.find((checkoutItem) => checkoutItem.id === id);
|
|
25
|
+
/* SizeChange and Booking */
|
|
43
26
|
const [isSizeChangeEnabled, sizeChangeEnabledStatus] = useViewIsSizeChangeEnabledByCheckoutId({
|
|
44
27
|
checkoutId: checkout?.id,
|
|
45
28
|
});
|
|
46
|
-
const
|
|
47
|
-
const [bookedProductsVariants] = useViewBookedProductsVariantsForCheckoutItem({
|
|
29
|
+
const [bookedProductsVariants, bookedProductsVariantsStatus] = useViewBookedProductsVariantsForCheckoutItem({
|
|
48
30
|
checkoutItemId: checkoutItem.id,
|
|
49
31
|
});
|
|
32
|
+
const isBookingRequired = bookedProductsVariants === null && isSizeChangeEnabled;
|
|
50
33
|
const [bookCheckoutBooking] = useBookCheckoutBookingForCheckoutItem({
|
|
51
34
|
checkoutItemId: checkoutItem.id,
|
|
52
35
|
checkoutBookingId: checkout?.checkoutBookingId,
|
|
53
36
|
logger,
|
|
54
37
|
});
|
|
55
|
-
|
|
38
|
+
// This reference is used for the effect not be triggered twice
|
|
39
|
+
// (bookCheckoutBooking changes when the checkout has a proper checkoutBookingId)
|
|
40
|
+
const bookCheckoutBookingRef = useRef(bookCheckoutBooking);
|
|
41
|
+
bookCheckoutBookingRef.current = bookCheckoutBooking;
|
|
56
42
|
useEffect(() => {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
: []
|
|
65
|
-
: undefined, [bookedProductsVariants, isSizeChangeEnabled, sizeChangeEnabledStatus]);
|
|
66
|
-
useTrackItemPageView({
|
|
67
|
-
page: TrackingPage.ITEM,
|
|
68
|
-
country,
|
|
69
|
-
checkoutId: checkout?.id,
|
|
43
|
+
if (isBookingRequired) {
|
|
44
|
+
bookCheckoutBookingRef.current();
|
|
45
|
+
}
|
|
46
|
+
}, [isBookingRequired]);
|
|
47
|
+
/* SizeChange and Booking */
|
|
48
|
+
/* ReturnCheckoutItem */
|
|
49
|
+
const [returnQuestions] = useListReturnQuestionsByCheckoutItemId({
|
|
70
50
|
checkoutItemId: checkoutItem.id,
|
|
71
|
-
productVariantId: checkoutItem.productVariant.id,
|
|
72
|
-
replaceableFor,
|
|
73
|
-
unique: checkoutItem.productVariant.size.unique,
|
|
74
51
|
});
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
52
|
+
const [returnQuestionsVisible, setReturnQuestionsVisible] = useState(false);
|
|
53
|
+
const showReturnQuestions = useCallback(() => setReturnQuestionsVisible(true), []);
|
|
54
|
+
const hideReturnQuestions = useCallback(() => setReturnQuestionsVisible(false), []);
|
|
55
|
+
const [returnCheckoutItem, returnCheckoutItemStatus] = useReturnCheckoutItem({
|
|
79
56
|
checkoutItemId: checkoutItem.id,
|
|
57
|
+
logger,
|
|
80
58
|
});
|
|
81
59
|
const trackReturnItem = useTrackReturnItem({
|
|
82
60
|
page: TrackingPage.ITEM,
|
|
@@ -84,99 +62,42 @@ const Item = ({ customerId, country }) => {
|
|
|
84
62
|
checkoutId: checkout?.id,
|
|
85
63
|
checkoutItemId: checkoutItem.id,
|
|
86
64
|
});
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
65
|
+
const returnItem = useCallback(async (feedbacks) => {
|
|
66
|
+
hideReturnQuestions();
|
|
67
|
+
returnCheckoutItem({ feedbacks });
|
|
68
|
+
trackReturnItem();
|
|
69
|
+
}, [hideReturnQuestions, returnCheckoutItem, trackReturnItem]);
|
|
70
|
+
/* ReturnCheckoutItem */
|
|
71
|
+
const replaceableFor = useMemo(() => sizeChangeEnabledStatus === QueryStatus.SUCCESS
|
|
72
|
+
? isSizeChangeEnabled
|
|
73
|
+
? bookedProductsVariants
|
|
74
|
+
? bookedProductsVariants?.productVariants.map(({ id }) => id)
|
|
75
|
+
: undefined
|
|
76
|
+
: []
|
|
77
|
+
: undefined, [bookedProductsVariants, isSizeChangeEnabled, sizeChangeEnabledStatus]);
|
|
78
|
+
useTrackItemPageView({
|
|
101
79
|
page: TrackingPage.ITEM,
|
|
102
80
|
country,
|
|
103
81
|
checkoutId: checkout?.id,
|
|
104
82
|
checkoutItemId: checkoutItem.id,
|
|
105
83
|
productVariantId: checkoutItem.productVariant.id,
|
|
84
|
+
replaceableFor,
|
|
85
|
+
unique: checkoutItem.productVariant.size.unique,
|
|
106
86
|
});
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
const [resetCheckoutItem, resetCheckoutItemStatus] = useResetCheckoutItem({
|
|
112
|
-
checkoutItemId: checkoutItem.id,
|
|
113
|
-
logger,
|
|
114
|
-
});
|
|
115
|
-
const [keepCheckoutItem, keepCheckoutItemStatus] = useKeepCheckoutItem({ checkoutItemId: checkoutItem.id, logger });
|
|
116
|
-
const [returnCheckoutItem, returnCheckoutItemStatus] = useReturnCheckoutItem({
|
|
117
|
-
checkoutItemId: checkoutItem.id,
|
|
118
|
-
logger,
|
|
119
|
-
});
|
|
120
|
-
const [replaceCheckoutItem, replaceCheckoutItemStatus] = useReplaceCheckoutItem({
|
|
121
|
-
checkoutItemId: checkoutItem.id,
|
|
122
|
-
logger,
|
|
123
|
-
});
|
|
124
|
-
const [sizeWithoutStockModalVisible, setSizeWithoutStockModalVisible] = useState(false);
|
|
125
|
-
const handleOnShowSizeWithoutStockModal = useCallback(() => setSizeWithoutStockModalVisible(true), []);
|
|
126
|
-
const handleOnHideSizeWithoutStockModal = useCallback(() => setSizeWithoutStockModalVisible(false), []);
|
|
127
|
-
const [returnQuestions, returnQuestionsStatus] = useListReturnQuestionsByCheckoutItemId({
|
|
128
|
-
checkoutItemId: checkoutItem.id,
|
|
129
|
-
});
|
|
130
|
-
const [stickyHeight, setStickyHeight] = useState(0);
|
|
131
|
-
const handleOnStickyLayout = useCallback(({ height }) => setStickyHeight(height), []);
|
|
132
|
-
const [returnQuestionsVisible, setReturnQuestionsVisible] = useState(false);
|
|
133
|
-
const handleOnShowReturnQuestions = useCallback(() => setReturnQuestionsVisible(true), []);
|
|
134
|
-
const handleOnHideReturnQuestions = useCallback(() => setReturnQuestionsVisible(false), []);
|
|
135
|
-
const handleOnEditFeedback = useCallback(() => handleOnShowReturnQuestions(), [handleOnShowReturnQuestions]);
|
|
136
|
-
const handleOnSubmit = useCallback((feedbacks) => {
|
|
137
|
-
handleOnHideReturnQuestions();
|
|
138
|
-
returnCheckoutItem({ feedbacks });
|
|
139
|
-
trackReturnItem();
|
|
140
|
-
}, [handleOnHideReturnQuestions, returnCheckoutItem, trackReturnItem]);
|
|
141
|
-
const handleOnReplace = useCallback((replacedForId) => {
|
|
142
|
-
replaceCheckoutItem({ replacedForId });
|
|
143
|
-
trackReplaceItem({ replaceFor: replacedForId });
|
|
144
|
-
}, [replaceCheckoutItem, trackReplaceItem]);
|
|
145
|
-
const handleOnReturn = useCallback(() => handleOnShowReturnQuestions(), [handleOnShowReturnQuestions]);
|
|
146
|
-
const handleOnKeep = useCallback(() => {
|
|
147
|
-
keepCheckoutItem();
|
|
148
|
-
trackKeepItem();
|
|
149
|
-
}, [keepCheckoutItem, trackKeepItem]);
|
|
150
|
-
const handleOnPressCustomerDecissionBanner = useCallback(() => {
|
|
151
|
-
resetCheckoutItem();
|
|
152
|
-
trackResetItem();
|
|
153
|
-
}, [resetCheckoutItem, trackResetItem]);
|
|
154
|
-
const handleOnChangedProductVariantSlider = useCallback((active) => trackImageView({ perspective: checkoutItem.productVariant.media[active]?.perspective }), [checkoutItem.productVariant.media, trackImageView]);
|
|
155
|
-
const productVariantSelected = useMemo(() => checkoutItem.status === CheckoutItemStatus.REPLACED && checkoutItem.replacedFor
|
|
156
|
-
? { id: checkoutItem.replacedFor.id, size: checkoutItem.replacedFor.size }
|
|
157
|
-
: { id: checkoutItem.productVariant.id, size: checkoutItem.productVariant.size }, [checkoutItem.productVariant.id, checkoutItem.productVariant.size, checkoutItem.replacedFor, checkoutItem.status]);
|
|
158
|
-
const dependenciesLoadedStatuses = [QueryStatus.ERROR, QueryStatus.SUCCESS];
|
|
159
|
-
const dependenciesLoaded = dependenciesLoadedStatuses.includes(returnQuestionsStatus) &&
|
|
160
|
-
dependenciesLoadedStatuses.includes(sizeChangeEnabledStatus) &&
|
|
87
|
+
const dependenciesLoaded = checkoutStatus !== QueryStatus.LOADING &&
|
|
88
|
+
checkout &&
|
|
89
|
+
checkoutItem &&
|
|
90
|
+
returnQuestions &&
|
|
161
91
|
// This will ensure that the view is not shown until bookCheckoutBooking use-case is dispatched (if required)
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
92
|
+
bookedProductsVariantsStatus !== QueryStatus.LOADING &&
|
|
93
|
+
sizeChangeEnabledStatus !== QueryStatus.LOADING &&
|
|
94
|
+
(isBookingRequired ? checkout.checkoutBookingId && bookedProductsVariants : true) &&
|
|
95
|
+
returnCheckoutItemStatus !== CommandStatus.LOADING;
|
|
96
|
+
if (!dependenciesLoaded) {
|
|
166
97
|
return React.createElement(Spinner, null);
|
|
167
|
-
|
|
168
|
-
const { media, brand, name, color } = checkoutItem.productVariant;
|
|
98
|
+
}
|
|
169
99
|
return (React.createElement(ReturnQuestionFeedbackProvider, { feedback: checkoutItem.feedbacks || {} },
|
|
170
|
-
React.createElement(
|
|
171
|
-
React.createElement(
|
|
172
|
-
React.createElement(Body, null,
|
|
173
|
-
customerDecissionMade && (React.createElement(CustomerDecissionBanner, { checkoutItemStatus: checkoutItem.status, onPress: handleOnPressCustomerDecissionBanner })),
|
|
174
|
-
React.createElement(View, { style: [style.content, { paddingBottom: Platform.OS === "web" ? spaceXL : stickyHeight }] },
|
|
175
|
-
React.createElement(View, { style: style.sliderContainer },
|
|
176
|
-
React.createElement(ProductVariantSlider, { producVariantMedia: media, onChanged: handleOnChangedProductVariantSlider })),
|
|
177
|
-
React.createElement(ProductVariantDescription, { brand: brand, color: color, country: country, name: name, price: price, size: productVariantSelected.size }),
|
|
178
|
-
checkoutItem.status === CheckoutItemStatus.RETURNED && (React.createElement(View, { style: style.feedbackContainer },
|
|
179
|
-
React.createElement(ReturnQuestionsFeedback, { returnQuestions: returnQuestions || [], onEditFeedback: handleOnEditFeedback })))))),
|
|
180
|
-
React.createElement(ReturnQuestionsForm, { checkoutItemPrice: checkoutItem.price, country: country, productVariant: checkoutItem.productVariant, returnQuestions: returnQuestions || [], visible: returnQuestionsVisible, onClose: handleOnHideReturnQuestions, onSubmit: handleOnSubmit })));
|
|
100
|
+
checkoutItem.status === CheckoutItemStatus.INITIAL ? (React.createElement(ItemWithoutCustomerDecission, { bookedProductsVariants: bookedProductsVariants, checkoutId: checkout.id, checkoutItem: checkoutItem, country: country, onReturn: showReturnQuestions })) : (React.createElement(ItemWithCustomerDecission, { checkoutId: checkout.id, checkoutItem: checkoutItem, country: country, returnQuestions: returnQuestions, onEditFeedback: showReturnQuestions })),
|
|
101
|
+
React.createElement(ReturnQuestionsForm, { checkoutItemPrice: checkoutItem.price, country: country, productVariant: checkoutItem.productVariant, returnQuestions: returnQuestions, visible: returnQuestionsVisible, onClose: hideReturnQuestions, onSubmit: returnItem })));
|
|
181
102
|
};
|
|
182
103
|
export { Item };
|
|
@@ -15,7 +15,7 @@ const CustomerDecissionBanner = ({ checkoutItemStatus, onPress }) => {
|
|
|
15
15
|
const decissionText = useI18nMessage({ id: i18nMessageForCheckoutItemStatus[checkoutItemStatus] }) || "";
|
|
16
16
|
const bannerButtonText = useI18nMessage({ id: I18nMessages.ITEM_BANNER_BUTTON });
|
|
17
17
|
return (React.createElement(Banner, { text: decissionText },
|
|
18
|
-
React.createElement(Pressable, { style: style.button, onPress: onPress },
|
|
18
|
+
React.createElement(Pressable, { style: style.button, testID: "customer-decission-banner", onPress: onPress },
|
|
19
19
|
React.createElement(Text, { level: 2, style: style.buttonText, detail: true }, bannerButtonText))));
|
|
20
20
|
};
|
|
21
21
|
export { CustomerDecissionBanner };
|
|
@@ -4,10 +4,7 @@ import { Country } from "../../../../../../projection/shared/country";
|
|
|
4
4
|
import { Layout } from "../../../../../../shared/ui/components/layouts/sticky/Sticky";
|
|
5
5
|
interface ItemActionsProps {
|
|
6
6
|
readonly productVariants?: ProductVariantProjection[];
|
|
7
|
-
readonly
|
|
8
|
-
readonly keepButtonLoading?: boolean;
|
|
9
|
-
readonly returnButtonLoading?: boolean;
|
|
10
|
-
readonly sizeSelectorDisabled?: boolean;
|
|
7
|
+
readonly currentProductVariant: ProductVariantProjection;
|
|
11
8
|
readonly country: Country;
|
|
12
9
|
readonly onSizeSelectorPress?: () => void;
|
|
13
10
|
readonly onKeep: () => void;
|
|
@@ -9,7 +9,7 @@ import { SelectField } from "../../../../../../shared/ui/components/molecules/se
|
|
|
9
9
|
import { Body } from "../../../../components/layouts/body/Body";
|
|
10
10
|
import { I18nMessages } from "../../../../i18n/i18n";
|
|
11
11
|
import { style } from "./ItemActions.style";
|
|
12
|
-
const ItemActions = ({ productVariants,
|
|
12
|
+
const ItemActions = ({ productVariants, currentProductVariant, country, onSizeSelectorPress = () => void 0, onKeep, onReplace, onReturn, onLayout, }) => {
|
|
13
13
|
const sizeSelectorLabelText = useI18nMessage({ id: I18nMessages.ITEM_SIZES_LABEL });
|
|
14
14
|
const keepButtonText = useI18nMessage({ id: I18nMessages.ITEM_KEEP_BUTTON });
|
|
15
15
|
const returnButtonText = useI18nMessage({ id: I18nMessages.ITEM_RETURN_BUTTON });
|
|
@@ -18,18 +18,18 @@ const ItemActions = ({ productVariants, productVariantSelected, keepButtonLoadin
|
|
|
18
18
|
value: productVariant.id,
|
|
19
19
|
})), [country, productVariants]);
|
|
20
20
|
const disabledSizeSelector = useMemo(() => sizeSelectorOptions.length === 0 ||
|
|
21
|
-
(sizeSelectorOptions.length === 1 && sizeSelectorOptions[0]?.value ===
|
|
21
|
+
(sizeSelectorOptions.length === 1 && sizeSelectorOptions[0]?.value === currentProductVariant.id), [sizeSelectorOptions, currentProductVariant.id]);
|
|
22
22
|
return (React.createElement(Sticky, { onLayout: onLayout },
|
|
23
23
|
React.createElement(Body, { style: { column: style.container } },
|
|
24
|
-
React.createElement(Button, {
|
|
24
|
+
React.createElement(Button, { onPress: onKeep }, keepButtonText),
|
|
25
25
|
React.createElement(View, { style: style.row },
|
|
26
|
-
!
|
|
26
|
+
!currentProductVariant.size.unique && productVariants && (React.createElement(SelectField, { ...(disabledSizeSelector && {
|
|
27
27
|
onPress: onSizeSelectorPress,
|
|
28
|
-
}),
|
|
28
|
+
}), options: sizeSelectorOptions, placeholder: sizeSelectorLabelText || "", testID: "size-selector", title: sizeSelectorLabelText || "", value: currentProductVariant.id, style: {
|
|
29
29
|
selectField: style.sizeSelector,
|
|
30
|
-
inputField: { input:
|
|
30
|
+
inputField: { input: disabledSizeSelector && style.inputDisabled },
|
|
31
31
|
}, onChange: onReplace })),
|
|
32
32
|
React.createElement(View, { style: style.returnButtonContainer },
|
|
33
|
-
React.createElement(Button, {
|
|
33
|
+
React.createElement(Button, { variant: BUTTON_VARIANT.SECONDARY, onPress: onReturn }, returnButtonText))))));
|
|
34
34
|
};
|
|
35
35
|
export { ItemActions };
|
|
@@ -23,7 +23,7 @@ const ReturnQuestionsFeedback = ({ returnQuestions, onEditFeedback }) => {
|
|
|
23
23
|
return (React.createElement(View, null,
|
|
24
24
|
React.createElement(View, { style: style.titleContainer },
|
|
25
25
|
React.createElement(Text, { level: 2, style: style.title }, titleText),
|
|
26
|
-
React.createElement(ButtonIcon, { name: "pencil", onPress: onEditFeedback })),
|
|
26
|
+
React.createElement(ButtonIcon, { name: "pencil", testID: "edit-feedback", onPress: onEditFeedback })),
|
|
27
27
|
React.createElement(ReturnQuestionItemProvider, { returnQuestionItems: returnQuestionItems },
|
|
28
28
|
React.createElement(ReturnQuestions, { returnQuestions: returnQuestions }))));
|
|
29
29
|
};
|
package/dist/infrastructure/ui/views/item/components/returnQuestionsForm/ReturnQuestionsForm.js
CHANGED
|
@@ -15,7 +15,7 @@ import { HostStackReturnQuestionItem } from "../../../../components/organisms/re
|
|
|
15
15
|
import { OptionReturnQuestionItem } from "../../../../components/organisms/returnQuestions/components/optionReturnQuestionItem/OptionReturnQuestionItem";
|
|
16
16
|
import { TextareaReturnQuestionItem } from "../../../../components/organisms/returnQuestions/components/textareaReturnQuestionItem/TextareaReturnQuestionItem";
|
|
17
17
|
import { I18nMessages } from "../../../../i18n/i18n";
|
|
18
|
-
import { ProductVariant } from "
|
|
18
|
+
import { ProductVariant } from "../../../shared/components/productVariant/ProductVariant";
|
|
19
19
|
import { style } from "./ReturnQuestionsForm.style";
|
|
20
20
|
const RETURN_QUESTION_FORM_PORTAL_HOST_NAME = "return-question-form-portal";
|
|
21
21
|
const returnQuestionItems = {
|
|
@@ -34,7 +34,7 @@ const ReturnQuestionsForm = ({ returnQuestions, checkoutItemPrice, productVarian
|
|
|
34
34
|
const handleOnSubmit = useCallback(() => onSubmit(feedback), [feedback, onSubmit]);
|
|
35
35
|
return (React.createElement(ReturnQuestionItemProvider, { returnQuestionItems: returnQuestionItems },
|
|
36
36
|
React.createElement(PortalHost, { name: RETURN_QUESTION_FORM_PORTAL_HOST_NAME }),
|
|
37
|
-
React.createElement(Modal, { footer: React.createElement(Button, { onPress: handleOnSubmit }, submitButtonText), portalHostName: RETURN_QUESTION_FORM_PORTAL_HOST_NAME, visible: visible, scroll: true, showCloseButton: true, onClose: onClose },
|
|
37
|
+
React.createElement(Modal, { footer: React.createElement(Button, { onPress: handleOnSubmit }, submitButtonText), portalHostName: RETURN_QUESTION_FORM_PORTAL_HOST_NAME, testID: "return-questions-form-modal", visible: visible, scroll: true, showCloseButton: true, onClose: onClose },
|
|
38
38
|
React.createElement(View, { style: style.returnQuestionsContainer },
|
|
39
39
|
React.createElement(Text, { level: 2, style: style.title }, titleText),
|
|
40
40
|
React.createElement(ProductVariant, { brand: brand, color: color, country: country, media: media, name: name, price: checkoutItemPrice, size: size }),
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { FC } from "react";
|
|
2
|
+
import { CheckoutItemStatus } from "../../../../../../domain/checkoutItem/model/checkoutItem";
|
|
3
|
+
import { CheckoutItemProjection } from "../../../../../../projection/checkoutItem/checkoutItem";
|
|
4
|
+
import { ReturnQuestionProjection } from "../../../../../../projection/returnQuestion/returnQuestion";
|
|
5
|
+
import { Country } from "../../../../../../projection/shared/country";
|
|
6
|
+
interface CheckoutItemWithCustomerDecission extends CheckoutItemProjection {
|
|
7
|
+
readonly status: Exclude<CheckoutItemStatus, CheckoutItemStatus.INITIAL>;
|
|
8
|
+
}
|
|
9
|
+
interface ItemWithCustomerDecissionProps {
|
|
10
|
+
readonly country: Country;
|
|
11
|
+
readonly checkoutId: string;
|
|
12
|
+
readonly checkoutItem: CheckoutItemWithCustomerDecission;
|
|
13
|
+
readonly returnQuestions: ReturnQuestionProjection[];
|
|
14
|
+
readonly onEditFeedback: () => void;
|
|
15
|
+
}
|
|
16
|
+
declare const ItemWithCustomerDecission: FC<ItemWithCustomerDecissionProps>;
|
|
17
|
+
export type { CheckoutItemWithCustomerDecission };
|
|
18
|
+
export { ItemWithCustomerDecission };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { CommandStatus } from "@lookiero/messaging-react";
|
|
2
|
+
import React, { useCallback, useMemo } from "react";
|
|
3
|
+
import { Platform, View } from "react-native";
|
|
4
|
+
import { CheckoutItemStatus } from "../../../../../../domain/checkoutItem/model/checkoutItem";
|
|
5
|
+
import { useLogger } from "../../../../../../shared/logging/useLogger";
|
|
6
|
+
import { useTrackResetItem } from "../../../../../../shared/tracking/infrastructure/useTrackResetItem";
|
|
7
|
+
import { Spinner } from "../../../../../../shared/ui/components/atoms/spinner/Spinner";
|
|
8
|
+
import { useResetCheckoutItem } from "../../../../../domain/checkoutItem/react/useResetCheckoutItem";
|
|
9
|
+
import { TrackingPage } from "../../../../../tracking/tracking";
|
|
10
|
+
import { Body } from "../../../../components/layouts/body/Body";
|
|
11
|
+
import { SafeAreaScrollView } from "../../../../components/templates/SafeAreaScrollView";
|
|
12
|
+
import { HEADER_HEIGHT } from "../../../navigation/components/header/Header.style";
|
|
13
|
+
import { CustomerDecissionBanner, } from "../../components/banner/CustomerDecissionBanner";
|
|
14
|
+
import { ReturnQuestionsFeedback } from "../../components/returnQuestionsFeedback/ReturnQuestionsFeedback";
|
|
15
|
+
import { ProductVariant } from "../../views/productVariant/ProductVariant";
|
|
16
|
+
import { style } from "./ItemWithCustomerDecission.style";
|
|
17
|
+
const ItemWithCustomerDecission = ({ country, checkoutId, checkoutItem, returnQuestions, onEditFeedback, }) => {
|
|
18
|
+
const logger = useLogger();
|
|
19
|
+
/* ResetCheckoutItem */
|
|
20
|
+
const [resetCheckoutItem, resetCheckoutItemStatus] = useResetCheckoutItem({
|
|
21
|
+
checkoutItemId: checkoutItem.id,
|
|
22
|
+
logger,
|
|
23
|
+
});
|
|
24
|
+
const trackResetItem = useTrackResetItem({
|
|
25
|
+
page: TrackingPage.ITEM,
|
|
26
|
+
country,
|
|
27
|
+
checkoutId,
|
|
28
|
+
checkoutItemId: checkoutItem.id,
|
|
29
|
+
});
|
|
30
|
+
const resetItem = useCallback(async () => {
|
|
31
|
+
resetCheckoutItem();
|
|
32
|
+
trackResetItem();
|
|
33
|
+
}, [resetCheckoutItem, trackResetItem]);
|
|
34
|
+
/* ResetCheckoutItem */
|
|
35
|
+
const currentProductVariant = useMemo(() => checkoutItem.status === CheckoutItemStatus.REPLACED && checkoutItem.replacedFor
|
|
36
|
+
? { id: checkoutItem.replacedFor.id, size: checkoutItem.replacedFor.size }
|
|
37
|
+
: { id: checkoutItem.productVariant.id, size: checkoutItem.productVariant.size }, [checkoutItem.productVariant.id, checkoutItem.productVariant.size, checkoutItem.replacedFor, checkoutItem.status]);
|
|
38
|
+
const dependenciesLoaded = resetCheckoutItemStatus !== CommandStatus.LOADING;
|
|
39
|
+
if (!dependenciesLoaded) {
|
|
40
|
+
return React.createElement(Spinner, null);
|
|
41
|
+
}
|
|
42
|
+
return (React.createElement(SafeAreaScrollView, { scrollerPaddingTop: Platform.OS === "web" || Platform.OS === "android" ? HEADER_HEIGHT : 0 },
|
|
43
|
+
React.createElement(Body, null,
|
|
44
|
+
React.createElement(CustomerDecissionBanner, { checkoutItemStatus: checkoutItem.status, onPress: resetItem }),
|
|
45
|
+
React.createElement(ProductVariant, { checkoutId: checkoutId, checkoutItem: checkoutItem, country: country, currentProductVariant: currentProductVariant }, checkoutItem.status === CheckoutItemStatus.RETURNED && (React.createElement(View, { style: style.feedbackContainer },
|
|
46
|
+
React.createElement(ReturnQuestionsFeedback, { returnQuestions: returnQuestions, onEditFeedback: onEditFeedback })))))));
|
|
47
|
+
};
|
|
48
|
+
export { ItemWithCustomerDecission };
|
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
import { StyleSheet } from "react-native";
|
|
2
|
-
import { theme } from "
|
|
2
|
+
import { theme } from "../../../../theme/theme";
|
|
3
3
|
const { borderSize, colorGrayscaleM, spaceXL } = theme();
|
|
4
4
|
const style = StyleSheet.create({
|
|
5
|
-
content: {
|
|
6
|
-
paddingHorizontal: spaceXL,
|
|
7
|
-
},
|
|
8
5
|
feedbackContainer: {
|
|
9
6
|
borderTopColor: colorGrayscaleM,
|
|
10
7
|
borderTopWidth: borderSize,
|
|
11
8
|
marginVertical: spaceXL,
|
|
12
9
|
},
|
|
13
|
-
sliderContainer: {
|
|
14
|
-
marginBottom: spaceXL,
|
|
15
|
-
minHeight: 500,
|
|
16
|
-
},
|
|
17
10
|
});
|
|
18
11
|
export { style };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { FC } from "react";
|
|
2
|
+
import { CheckoutItemStatus } from "../../../../../../domain/checkoutItem/model/checkoutItem";
|
|
3
|
+
import { BookedProductsVariantsProjection } from "../../../../../../projection/bookedProductsVariants/bookedProductsVariants";
|
|
4
|
+
import "../../../../../../projection/checkout/viewFirstAvailableCheckoutByCustomerId";
|
|
5
|
+
import { CheckoutItemProjection } from "../../../../../../projection/checkoutItem/checkoutItem";
|
|
6
|
+
import { Country } from "../../../../../../projection/shared/country";
|
|
7
|
+
interface CheckoutItemWithoutCustomerDecission extends CheckoutItemProjection {
|
|
8
|
+
readonly status: CheckoutItemStatus.INITIAL;
|
|
9
|
+
}
|
|
10
|
+
interface ItemWithoutCustomerDecissionProps {
|
|
11
|
+
readonly country: Country;
|
|
12
|
+
readonly checkoutId: string;
|
|
13
|
+
readonly checkoutItem: CheckoutItemWithoutCustomerDecission;
|
|
14
|
+
readonly bookedProductsVariants: BookedProductsVariantsProjection;
|
|
15
|
+
readonly onReturn: () => void;
|
|
16
|
+
}
|
|
17
|
+
declare const ItemWithoutCustomerDecission: FC<ItemWithoutCustomerDecissionProps>;
|
|
18
|
+
export type { CheckoutItemWithoutCustomerDecission };
|
|
19
|
+
export { ItemWithoutCustomerDecission };
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { CommandStatus } from "@lookiero/messaging-react";
|
|
2
|
+
import React, { useCallback, useMemo, useState } from "react";
|
|
3
|
+
import { Platform } from "react-native";
|
|
4
|
+
import "../../../../../../projection/checkout/viewFirstAvailableCheckoutByCustomerId";
|
|
5
|
+
import { useLogger } from "../../../../../../shared/logging/useLogger";
|
|
6
|
+
import { useTrackKeepItem } from "../../../../../../shared/tracking/infrastructure/useTrackKeepItem";
|
|
7
|
+
import { useTrackReplaceItem } from "../../../../../../shared/tracking/infrastructure/useTrackReplaceItem";
|
|
8
|
+
import { Spinner } from "../../../../../../shared/ui/components/atoms/spinner/Spinner";
|
|
9
|
+
import { useKeepCheckoutItem } from "../../../../../domain/checkoutItem/react/useKeepCheckoutItem";
|
|
10
|
+
import { useReplaceCheckoutItem } from "../../../../../domain/checkoutItem/react/useReplaceCheckoutItem";
|
|
11
|
+
import { TrackingPage } from "../../../../../tracking/tracking";
|
|
12
|
+
import { Body } from "../../../../components/layouts/body/Body";
|
|
13
|
+
import { SafeAreaScrollView } from "../../../../components/templates/SafeAreaScrollView";
|
|
14
|
+
import { theme } from "../../../../theme/theme";
|
|
15
|
+
import { HEADER_HEIGHT } from "../../../navigation/components/header/Header.style";
|
|
16
|
+
import { ItemActions } from "../../components/itemActions/ItemActions";
|
|
17
|
+
import { SizeWithoutStockModal } from "../../components/sizeWithoutStockModal/SizeWithoutStockModal";
|
|
18
|
+
import { ProductVariant } from "../productVariant/ProductVariant";
|
|
19
|
+
const { spaceXL } = theme();
|
|
20
|
+
const ItemWithoutCustomerDecission = ({ country, checkoutId, checkoutItem, bookedProductsVariants, onReturn, }) => {
|
|
21
|
+
const logger = useLogger();
|
|
22
|
+
/* KeepCheckoutItem */
|
|
23
|
+
const [keepCheckoutItem, keepCheckoutItemStatus] = useKeepCheckoutItem({ checkoutItemId: checkoutItem.id, logger });
|
|
24
|
+
const trackKeepItem = useTrackKeepItem({
|
|
25
|
+
page: TrackingPage.ITEM,
|
|
26
|
+
country,
|
|
27
|
+
checkoutId,
|
|
28
|
+
checkoutItemId: checkoutItem.id,
|
|
29
|
+
});
|
|
30
|
+
const handleOnKeep = useCallback(() => {
|
|
31
|
+
keepCheckoutItem();
|
|
32
|
+
trackKeepItem();
|
|
33
|
+
}, [keepCheckoutItem, trackKeepItem]);
|
|
34
|
+
/* KeepCheckoutItem */
|
|
35
|
+
/* ReplaceCheckoutItem */
|
|
36
|
+
const [replaceCheckoutItem, replaceCheckoutItemStatus] = useReplaceCheckoutItem({
|
|
37
|
+
checkoutItemId: checkoutItem.id,
|
|
38
|
+
logger,
|
|
39
|
+
});
|
|
40
|
+
const trackReplaceItem = useTrackReplaceItem({
|
|
41
|
+
page: TrackingPage.ITEM,
|
|
42
|
+
country,
|
|
43
|
+
checkoutId,
|
|
44
|
+
checkoutItemId: checkoutItem.id,
|
|
45
|
+
productVariantId: checkoutItem.productVariant.id,
|
|
46
|
+
});
|
|
47
|
+
const handleOnReplace = useCallback((replacedForId) => {
|
|
48
|
+
replaceCheckoutItem({ replacedForId });
|
|
49
|
+
trackReplaceItem({ replaceFor: replacedForId });
|
|
50
|
+
}, [replaceCheckoutItem, trackReplaceItem]);
|
|
51
|
+
/* ReplaceCheckoutItem */
|
|
52
|
+
const [sizeWithoutStockModalVisible, setSizeWithoutStockModalVisible] = useState(false);
|
|
53
|
+
const handleOnShowSizeWithoutStockModal = useCallback(() => setSizeWithoutStockModalVisible(true), []);
|
|
54
|
+
const handleOnHideSizeWithoutStockModal = useCallback(() => setSizeWithoutStockModalVisible(false), []);
|
|
55
|
+
const [stickyHeight, setStickyHeight] = useState(0);
|
|
56
|
+
const handleOnStickyLayout = useCallback(({ height }) => setStickyHeight(height), []);
|
|
57
|
+
const currentProductVariant = useMemo(() => ({ id: checkoutItem.productVariant.id, size: checkoutItem.productVariant.size }), [checkoutItem.productVariant.id, checkoutItem.productVariant.size]);
|
|
58
|
+
const dependenciesLoaded = keepCheckoutItemStatus !== CommandStatus.LOADING && replaceCheckoutItemStatus !== CommandStatus.LOADING;
|
|
59
|
+
if (!dependenciesLoaded) {
|
|
60
|
+
return React.createElement(Spinner, null);
|
|
61
|
+
}
|
|
62
|
+
return (React.createElement(React.Fragment, null,
|
|
63
|
+
React.createElement(SizeWithoutStockModal, { visible: sizeWithoutStockModalVisible, onDismiss: handleOnHideSizeWithoutStockModal }),
|
|
64
|
+
React.createElement(SafeAreaScrollView, { scrollerPaddingTop: Platform.OS === "web" || Platform.OS === "android" ? HEADER_HEIGHT : 0, footer: React.createElement(ItemActions, { country: country, currentProductVariant: currentProductVariant, productVariants: bookedProductsVariants?.productVariants, onKeep: handleOnKeep, onLayout: handleOnStickyLayout, onReplace: handleOnReplace, onReturn: onReturn, onSizeSelectorPress: handleOnShowSizeWithoutStockModal }) },
|
|
65
|
+
React.createElement(Body, null,
|
|
66
|
+
React.createElement(ProductVariant, { checkoutId: checkoutId, checkoutItem: checkoutItem, country: country, currentProductVariant: currentProductVariant, style: { content: { paddingBottom: Platform.OS === "web" ? spaceXL : stickyHeight } } })))));
|
|
67
|
+
};
|
|
68
|
+
export { ItemWithoutCustomerDecission };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { FC, ReactNode } from "react";
|
|
2
|
+
import { StyleProp, ViewStyle } from "react-native";
|
|
3
|
+
import { ProductVariantProjection } from "../../../../../../projection/bookedProductsVariants/bookedProductsVariants";
|
|
4
|
+
import { CheckoutItemProjection } from "../../../../../../projection/checkoutItem/checkoutItem";
|
|
5
|
+
import { Country } from "../../../../../../projection/shared/country";
|
|
6
|
+
type ProductVariantStyle = "content";
|
|
7
|
+
interface ProductVariantProps {
|
|
8
|
+
readonly country: Country;
|
|
9
|
+
readonly checkoutId: string;
|
|
10
|
+
readonly checkoutItem: CheckoutItemProjection;
|
|
11
|
+
readonly currentProductVariant: ProductVariantProjection;
|
|
12
|
+
readonly style?: Partial<Record<ProductVariantStyle, StyleProp<ViewStyle>>>;
|
|
13
|
+
readonly children?: ReactNode;
|
|
14
|
+
}
|
|
15
|
+
declare const ProductVariant: FC<ProductVariantProps>;
|
|
16
|
+
export { ProductVariant };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React, { useCallback, useEffect } from "react";
|
|
2
|
+
import { View } from "react-native";
|
|
3
|
+
import { useTrackImageView } from "../../../../../../shared/tracking/infrastructure/useTrackImageView";
|
|
4
|
+
import { TrackingPage } from "../../../../../tracking/tracking";
|
|
5
|
+
import { ProductVariantDescription } from "../../components/productVariantDescription/ProductVariantDescription";
|
|
6
|
+
import { ProductVariantSlider } from "../../components/productVariantSlider/ProductVariantSlider";
|
|
7
|
+
import { style } from "./ProductVariant.style";
|
|
8
|
+
const ProductVariant = ({ country, checkoutId, checkoutItem, currentProductVariant, style: customStyle, children, }) => {
|
|
9
|
+
const trackImageView = useTrackImageView({
|
|
10
|
+
page: TrackingPage.ITEM,
|
|
11
|
+
country,
|
|
12
|
+
checkoutId,
|
|
13
|
+
checkoutItemId: checkoutItem.id,
|
|
14
|
+
productVariantId: checkoutItem.productVariant.id,
|
|
15
|
+
});
|
|
16
|
+
useEffect(() => trackImageView({
|
|
17
|
+
perspective: checkoutItem.productVariant.media[0]?.perspective,
|
|
18
|
+
}), [checkoutItem.productVariant.media, trackImageView]);
|
|
19
|
+
const handleOnChangedProductVariantSlider = useCallback((active) => trackImageView({ perspective: checkoutItem.productVariant.media[active]?.perspective }), [checkoutItem.productVariant.media, trackImageView]);
|
|
20
|
+
const { price } = checkoutItem;
|
|
21
|
+
const { media, brand, name, color } = checkoutItem.productVariant;
|
|
22
|
+
return (React.createElement(View, { style: [style.content, customStyle?.content], testID: "product-variant" },
|
|
23
|
+
React.createElement(View, { style: style.sliderContainer },
|
|
24
|
+
React.createElement(ProductVariantSlider, { producVariantMedia: media, onChanged: handleOnChangedProductVariantSlider })),
|
|
25
|
+
React.createElement(ProductVariantDescription, { brand: brand, color: color, country: country, name: name, price: price, size: currentProductVariant.size }),
|
|
26
|
+
children));
|
|
27
|
+
};
|
|
28
|
+
export { ProductVariant };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { StyleSheet } from "react-native";
|
|
2
|
+
import { theme } from "../../../../theme/theme";
|
|
3
|
+
const { spaceXL } = theme();
|
|
4
|
+
const style = StyleSheet.create({
|
|
5
|
+
content: {
|
|
6
|
+
paddingHorizontal: spaceXL,
|
|
7
|
+
},
|
|
8
|
+
sliderContainer: {
|
|
9
|
+
marginBottom: spaceXL,
|
|
10
|
+
minHeight: 500,
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
export { style };
|
|
@@ -10,22 +10,22 @@ import { Header } from "./components/header/Header";
|
|
|
10
10
|
const Navigation = ({ customerId, country, menu, tabBar: TabBar, children }) => {
|
|
11
11
|
const [menuVisible, setMenuVisible] = useState(false);
|
|
12
12
|
const trackPressMenu = useTrackPressMenu();
|
|
13
|
-
const handleOnOpenMenu = useCallback(({ page, checkoutId,
|
|
13
|
+
const handleOnOpenMenu = useCallback(({ page, checkoutId, collapse }) => {
|
|
14
14
|
setMenuVisible(true);
|
|
15
15
|
trackPressMenu({
|
|
16
16
|
page,
|
|
17
17
|
country,
|
|
18
18
|
checkoutId,
|
|
19
|
-
|
|
19
|
+
collapse,
|
|
20
20
|
});
|
|
21
21
|
}, [country, trackPressMenu]);
|
|
22
|
-
const handleOnCloseMenu = useCallback(({ page, checkoutId,
|
|
22
|
+
const handleOnCloseMenu = useCallback(({ page, checkoutId, collapse }) => {
|
|
23
23
|
setMenuVisible(false);
|
|
24
24
|
trackPressMenu({
|
|
25
25
|
page,
|
|
26
26
|
country,
|
|
27
27
|
checkoutId,
|
|
28
|
-
|
|
28
|
+
collapse,
|
|
29
29
|
});
|
|
30
30
|
}, [country, trackPressMenu]);
|
|
31
31
|
const trackPressBack = useTrackPressBack();
|
|
@@ -5,7 +5,7 @@ import { Menu } from "../../Navigation";
|
|
|
5
5
|
interface OnOpenMenuFunctionArgs {
|
|
6
6
|
readonly page: TrackingPage;
|
|
7
7
|
readonly checkoutId: string | undefined;
|
|
8
|
-
readonly
|
|
8
|
+
readonly collapse: boolean;
|
|
9
9
|
}
|
|
10
10
|
interface OnOpenMenuFunction {
|
|
11
11
|
(args: OnOpenMenuFunctionArgs): void;
|
|
@@ -13,7 +13,7 @@ interface OnOpenMenuFunction {
|
|
|
13
13
|
interface OnCloseMenuFunctionArgs {
|
|
14
14
|
readonly page: TrackingPage;
|
|
15
15
|
readonly checkoutId: string | undefined;
|
|
16
|
-
readonly
|
|
16
|
+
readonly collapse: boolean;
|
|
17
17
|
}
|
|
18
18
|
interface OnCloseMenuFunction {
|
|
19
19
|
(args: OnCloseMenuFunctionArgs): void;
|
|
@@ -96,8 +96,8 @@ const Header = ({ customerId, menu: Menu, menuVisible, onOpenMenu, onCloseMenu,
|
|
|
96
96
|
summaryRouteMatch,
|
|
97
97
|
]);
|
|
98
98
|
const { top: safeAreaInsetTop } = useSafeAreaInsets();
|
|
99
|
-
const handleOnOpenMenu = useCallback(() => onOpenMenu({ page: trackingPage(), checkoutId: checkout?.id,
|
|
100
|
-
const handleOnCloseMenu = useCallback(() => onCloseMenu({ page: trackingPage(), checkoutId: checkout?.id,
|
|
99
|
+
const handleOnOpenMenu = useCallback(() => onOpenMenu({ page: trackingPage(), checkoutId: checkout?.id, collapse: false }), [checkout?.id, onOpenMenu, trackingPage]);
|
|
100
|
+
const handleOnCloseMenu = useCallback(() => onCloseMenu({ page: trackingPage(), checkoutId: checkout?.id, collapse: true }), [checkout?.id, onCloseMenu, trackingPage]);
|
|
101
101
|
const handleOnBack = useCallback(() => onBack?.({ page: trackingPage(), checkoutId: checkout?.id }), [checkout?.id, onBack, trackingPage]);
|
|
102
102
|
const handleOnNext = useCallback(({ from, to }) => onNext?.({ page: trackingPage(), checkoutId: checkout?.id, from, to }), [checkout?.id, onNext, trackingPage]);
|
|
103
103
|
const handleOnPrevious = useCallback(({ from, to }) => onPrevious?.({ page: trackingPage(), checkoutId: checkout?.id, from, to }), [checkout?.id, onPrevious, trackingPage]);
|
package/dist/infrastructure/ui/views/summary/components/checkoutItemsTabs/CheckoutItemsTabs.js
CHANGED
|
@@ -5,7 +5,7 @@ import { View } from "react-native";
|
|
|
5
5
|
import { CheckoutItemStatus } from "../../../../../../domain/checkoutItem/model/checkoutItem";
|
|
6
6
|
import { Tabs } from "../../../../components/layouts/tabs/Tabs";
|
|
7
7
|
import { I18nMessages } from "../../../../i18n/i18n";
|
|
8
|
-
import { ProductVariant } from "../../../
|
|
8
|
+
import { ProductVariant } from "../../../shared/components/productVariant/ProductVariant";
|
|
9
9
|
import { style } from "./CheckoutItemsTabs.style";
|
|
10
10
|
const CheckoutItem = ({ checkoutItemStatus, checkoutItemProductVariant, checkoutItemPrice, country, discarded = false, testID, style: customStyle, onPress, }) => (React.createElement(View, { style: style.checkoutItem, testID: testID },
|
|
11
11
|
React.createElement(ProductVariant, { brand: checkoutItemProductVariant.brand, color: checkoutItemProductVariant.color, country: country, discarded: discarded, media: checkoutItemProductVariant.media, name: checkoutItemProductVariant.name, price: checkoutItemPrice, size: checkoutItemProductVariant.size, status: checkoutItemStatus, style: customStyle, onPress: onPress })));
|
|
@@ -4,7 +4,7 @@ interface PressMenuFunctionArgs {
|
|
|
4
4
|
readonly page: TrackingPage;
|
|
5
5
|
readonly country: Country;
|
|
6
6
|
readonly checkoutId: string | undefined;
|
|
7
|
-
readonly
|
|
7
|
+
readonly collapse: boolean;
|
|
8
8
|
}
|
|
9
9
|
interface PressMenuFunction {
|
|
10
10
|
(args: PressMenuFunctionArgs): void;
|
|
@@ -4,7 +4,7 @@ import { TrackingEvent, TrackingEventCategory } from "../tracking";
|
|
|
4
4
|
import { useEmitUserEvent } from "./useEmitUserEvent";
|
|
5
5
|
const useTrackPressMenu = () => {
|
|
6
6
|
const emitUserEvent = useEmitUserEvent();
|
|
7
|
-
const pressMenu = useCallback(({ page, country, checkoutId,
|
|
7
|
+
const pressMenu = useCallback(({ page, country, checkoutId, collapse }) => {
|
|
8
8
|
if (!checkoutId) {
|
|
9
9
|
return;
|
|
10
10
|
}
|
|
@@ -14,7 +14,7 @@ const useTrackPressMenu = () => {
|
|
|
14
14
|
section: `${PROJECT}_${page}`,
|
|
15
15
|
store: country,
|
|
16
16
|
checkoutId,
|
|
17
|
-
|
|
17
|
+
collapse,
|
|
18
18
|
};
|
|
19
19
|
emitUserEvent(pressMenuTrackingEvent);
|
|
20
20
|
}, [emitUserEvent]);
|
|
@@ -69,7 +69,7 @@ interface ChangeFeedbackTrackingEvent extends BaseTrackingEvent {
|
|
|
69
69
|
readonly feedback: string | undefined;
|
|
70
70
|
}
|
|
71
71
|
interface PressMenuTrackingEvent extends BaseTrackingEvent {
|
|
72
|
-
readonly
|
|
72
|
+
readonly collapse: boolean;
|
|
73
73
|
}
|
|
74
74
|
type PressBackTrackingEvent = BaseTrackingEvent;
|
|
75
75
|
interface PressNextTrackingEvent extends BaseTrackingEvent {
|
|
@@ -3,5 +3,5 @@ import React from "react";
|
|
|
3
3
|
import { View } from "react-native";
|
|
4
4
|
import { style } from "./Spinner.style";
|
|
5
5
|
const Spinner = () => (React.createElement(View, { style: style.container },
|
|
6
|
-
React.createElement(AuroraSpinner,
|
|
6
|
+
React.createElement(AuroraSpinner, { testID: "spinner" })));
|
|
7
7
|
export { Spinner };
|
|
@@ -19,7 +19,7 @@ const SelectField = ({ title, placeholder, value, options, style: customStyle, o
|
|
|
19
19
|
React.createElement(TouchableHighlight, { style: customStyle?.selectField, underlayColor: colorGrayscaleS, onPress: handleOnPressSelectField, ...touchableRestProps },
|
|
20
20
|
React.createElement(View, { pointerEvents: "none" },
|
|
21
21
|
React.createElement(InputField, { editable: false, icon: "arrow-down", label: placeholder, style: customStyle?.inputField, value: selectedValue?.label }))),
|
|
22
|
-
React.createElement(Modal, { visible: modalVisible, scroll: true, showCloseButton: true, onClose: handleOnModalClose },
|
|
22
|
+
React.createElement(Modal, { testID: "select-field-modal", visible: modalVisible, scroll: true, showCloseButton: true, onClose: handleOnModalClose },
|
|
23
23
|
React.createElement(View, { style: [style.modalContent, customStyle?.modalContent] },
|
|
24
24
|
title && (React.createElement(Text, { level: 2, style: style.modalTitle }, title)),
|
|
25
25
|
options.map(({ label, value: optionValue }) => (React.createElement(TouchableHighlight, { key: optionValue, disabled: value === optionValue, style: [style.option, customStyle?.option], underlayColor: colorGrayscaleS, onPress: value !== optionValue ? () => handleOnPressOption(optionValue) : undefined },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lookiero/checkout",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"@lookiero/i18n-react": "^0.8.3",
|
|
33
33
|
"@lookiero/messaging": "^8.1.1",
|
|
34
34
|
"@lookiero/messaging-react": "^8.1.1",
|
|
35
|
-
"@react-spring/native": "
|
|
35
|
+
"@react-spring/native": "9.6.1",
|
|
36
36
|
"@sentry/react-native": "^4.13.0",
|
|
37
37
|
"inline-style-prefixer": "6.0.1",
|
|
38
38
|
"lodash": "^4.17.21",
|
/package/dist/infrastructure/ui/views/{item → shared}/components/productVariant/ProductVariant.d.ts
RENAMED
|
File without changes
|
/package/dist/infrastructure/ui/views/{item → shared}/components/productVariant/ProductVariant.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|