@lookiero/checkout 6.6.0 → 7.0.0-beta.0

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 (91) hide show
  1. package/dist/index.d.ts +0 -8
  2. package/dist/index.js +0 -3
  3. package/dist/public/public/assets/adaptive-icon.png +0 -0
  4. package/dist/public/public/assets/favicon.png +0 -0
  5. package/dist/public/public/assets/icon.png +0 -0
  6. package/dist/public/public/assets/splash.png +0 -0
  7. package/dist/public/public/images/not-found.png +0 -0
  8. package/dist/src/Expo.js +0 -2
  9. package/dist/src/ExpoRoot.js +8 -1
  10. package/dist/src/infrastructure/ab-testing/kameleoonEnvironment.d.ts +6 -2
  11. package/dist/src/infrastructure/delivery/baseBootstrap.js +0 -2
  12. package/dist/src/infrastructure/ui/components/layouts/layout/Layout.d.ts +21 -0
  13. package/dist/src/infrastructure/ui/components/layouts/layout/Layout.js +1 -0
  14. package/dist/src/infrastructure/ui/components/layouts/layout/components/footer/Footer.d.ts +6 -0
  15. package/dist/src/infrastructure/ui/components/layouts/layout/components/footer/Footer.js +4 -0
  16. package/dist/src/infrastructure/ui/components/layouts/layout/components/header/Header.d.ts +6 -0
  17. package/dist/src/infrastructure/ui/components/layouts/layout/components/header/Header.js +5 -0
  18. package/dist/src/infrastructure/ui/components/layouts/layout/components/header/Header.style.d.ts +4 -0
  19. package/dist/src/infrastructure/ui/components/layouts/layout/components/header/Header.style.js +19 -0
  20. package/dist/src/infrastructure/ui/components/layouts/layout/dummyLayout/DummyLayout.d.ts +3 -0
  21. package/dist/src/infrastructure/ui/components/layouts/layout/dummyLayout/DummyLayout.js +18 -0
  22. package/dist/src/infrastructure/ui/components/layouts/layout/dummyLayout/DummyLayout.style.d.ts +12 -0
  23. package/dist/src/infrastructure/ui/components/layouts/layout/dummyLayout/DummyLayout.style.js +13 -0
  24. package/dist/src/infrastructure/ui/components/organisms/returnQuestions/components/hostDefaultReturnQuestionItem/HostDefaultReturnQuestionItem.js +10 -1
  25. package/dist/src/infrastructure/ui/components/organisms/returnQuestions/components/hostDefaultReturnQuestionItem/HostDefaultReturnQuestionItem.style.d.ts +7 -1
  26. package/dist/src/infrastructure/ui/components/organisms/returnQuestions/components/hostDefaultReturnQuestionItem/HostDefaultReturnQuestionItem.style.js +7 -1
  27. package/dist/src/infrastructure/ui/components/organisms/returnQuestions/components/textareaReturnQuestionItem/TextareaReturnQuestionItem.js +7 -2
  28. package/dist/src/infrastructure/ui/components/templates/header/defaultHeader/DefaultHeader.d.ts +6 -0
  29. package/dist/src/infrastructure/ui/components/templates/header/defaultHeader/DefaultHeader.js +11 -0
  30. package/dist/src/infrastructure/ui/components/templates/header/defaultHeader/DefaultHeader.style.d.ts +8 -0
  31. package/dist/src/infrastructure/ui/components/templates/header/defaultHeader/DefaultHeader.style.js +11 -0
  32. package/dist/src/infrastructure/ui/hooks/useNewFeedbackExperiment.d.ts +11 -0
  33. package/dist/src/infrastructure/ui/hooks/useNewFeedbackExperiment.js +49 -0
  34. package/dist/src/infrastructure/ui/routing/Routing.js +13 -13
  35. package/dist/src/infrastructure/ui/views/checkout/Checkout.js +4 -4
  36. package/dist/src/infrastructure/ui/views/feedback/Feedback.d.ts +2 -2
  37. package/dist/src/infrastructure/ui/views/feedback/components/checkoutQuestionsForm/CheckoutQuestionsForm.style.d.ts +7 -0
  38. package/dist/src/infrastructure/ui/views/feedback/components/checkoutQuestionsForm/CheckoutQuestionsForm.style.js +10 -0
  39. package/dist/src/infrastructure/ui/views/item/Item.js +33 -4
  40. package/dist/src/infrastructure/ui/views/item/components/returnQuestionsForm/ReturnQuestionsForm.d.ts +11 -0
  41. package/dist/src/infrastructure/ui/views/item/components/returnQuestionsForm/ReturnQuestionsForm.js +40 -0
  42. package/dist/src/infrastructure/ui/views/item/components/returnQuestionsForm/ReturnQuestionsForm.style.d.ts +12 -0
  43. package/dist/src/infrastructure/ui/views/item/components/returnQuestionsForm/ReturnQuestionsForm.style.js +15 -0
  44. package/dist/src/infrastructure/ui/views/return/Return.js +127 -8
  45. package/dist/src/infrastructure/ui/views/return/components/productVariantPreview/ProductVariantPreview.js +7 -5
  46. package/dist/src/infrastructure/ui/views/summary/Summary.js +4 -4
  47. package/dist/src/infrastructure/ui/views/summary/components/stickyPricing/StickyPricing.d.ts +13 -0
  48. package/dist/src/infrastructure/ui/views/summary/components/stickyPricing/StickyPricing.js +9 -0
  49. package/dist/src/infrastructure/ui/views/summary/components/stickyPricing/StickyPricing.style.d.ts +7 -0
  50. package/dist/src/infrastructure/ui/views/summary/components/stickyPricing/StickyPricing.style.js +10 -0
  51. package/dist/src/version.d.ts +1 -1
  52. package/dist/src/version.js +1 -1
  53. package/index.ts +0 -17
  54. package/package.json +1 -3
  55. package/src/Expo.tsx +0 -3
  56. package/src/ExpoRoot.tsx +8 -1
  57. package/src/infrastructure/ab-testing/kameleoonEnvironment.ts +7 -3
  58. package/src/infrastructure/delivery/baseBootstrap.ts +0 -5
  59. package/src/infrastructure/ui/components/organisms/returnQuestions/components/hostDefaultReturnQuestionItem/HostDefaultReturnQuestionItem.style.ts +7 -1
  60. package/src/infrastructure/ui/components/organisms/returnQuestions/components/hostDefaultReturnQuestionItem/HostDefaultReturnQuestionItem.test.tsx +5 -0
  61. package/src/infrastructure/ui/components/organisms/returnQuestions/components/hostDefaultReturnQuestionItem/HostDefaultReturnQuestionItem.tsx +17 -2
  62. package/src/infrastructure/ui/components/organisms/returnQuestions/components/textareaReturnQuestionItem/TextareaReturnQuestionItem.test.tsx +5 -0
  63. package/src/infrastructure/ui/components/organisms/returnQuestions/components/textareaReturnQuestionItem/TextareaReturnQuestionItem.tsx +20 -11
  64. package/src/infrastructure/ui/hooks/useNewFeedbackExperiment.test.tsx +84 -0
  65. package/src/infrastructure/ui/hooks/useNewFeedbackExperiment.tsx +82 -0
  66. package/src/infrastructure/ui/routing/Routing.tsx +18 -21
  67. package/src/infrastructure/ui/views/checkout/Checkout.tsx +6 -6
  68. package/src/infrastructure/ui/views/feedback/Feedback.tsx +2 -2
  69. package/src/infrastructure/ui/views/item/Item.test.tsx +62 -6
  70. package/src/infrastructure/ui/views/item/Item.tsx +48 -5
  71. package/src/infrastructure/ui/views/item/components/returnQuestionsForm/ReturnQuestionsForm.style.ts +18 -0
  72. package/src/infrastructure/ui/views/item/components/returnQuestionsForm/ReturnQuestionsForm.tsx +79 -0
  73. package/src/infrastructure/ui/views/return/Return.tsx +200 -12
  74. package/src/infrastructure/ui/views/return/components/productVariantPreview/ProductVariantPreview.tsx +7 -12
  75. package/src/infrastructure/ui/views/summary/Summary.tsx +6 -6
  76. package/dist/src/infrastructure/ui/views/return/components/returnQuestionsForm/ReturnQuestionsForm.d.ts +0 -15
  77. package/dist/src/infrastructure/ui/views/return/components/returnQuestionsForm/ReturnQuestionsForm.js +0 -112
  78. package/src/infrastructure/projection/checkout/react/useViewIsCheckoutAccessibleByCustomerId.test.ts +0 -45
  79. package/src/infrastructure/projection/checkout/react/useViewIsCheckoutAccessibleByCustomerId.ts +0 -33
  80. package/src/infrastructure/ui/routing/CheckoutAccessibilityMiddleware.test.tsx +0 -74
  81. package/src/infrastructure/ui/routing/CheckoutAccessibilityMiddleware.tsx +0 -39
  82. package/src/infrastructure/ui/views/return/Return.test.tsx +0 -54
  83. package/src/infrastructure/ui/views/return/components/productVariantPreview/ProductVariantPreview.test.tsx +0 -32
  84. package/src/infrastructure/ui/views/return/components/productVariantPreview/__snapshots__/ProductVariantPreview.test.tsx.snap +0 -221
  85. package/src/infrastructure/ui/views/return/components/returnQuestionsForm/ReturnQuestionsForm.test.tsx +0 -95
  86. package/src/infrastructure/ui/views/return/components/returnQuestionsForm/ReturnQuestionsForm.tsx +0 -184
  87. package/src/projection/checkout/viewIsCheckoutAccessibleByCustomerId.test.ts +0 -54
  88. package/src/projection/checkout/viewIsCheckoutAccessibleByCustomerId.ts +0 -46
  89. /package/dist/src/infrastructure/ui/views/return/{components/returnQuestionsForm/ReturnQuestionsForm.style.d.ts → Return.style.d.ts} +0 -0
  90. /package/dist/src/infrastructure/ui/views/return/{components/returnQuestionsForm/ReturnQuestionsForm.style.js → Return.style.js} +0 -0
  91. /package/src/infrastructure/ui/views/return/{components/returnQuestionsForm/ReturnQuestionsForm.style.ts → Return.style.ts} +0 -0
@@ -1,7 +1,7 @@
1
- import React, { FC, useCallback, useEffect, useMemo, useRef } from "react";
1
+ import React, { FC, useCallback, useEffect, useMemo, useRef, useState } from "react";
2
2
  import { generatePath, useMatch, useNavigate, useParams } from "react-router-native";
3
3
  import { Box, Spinner } from "@lookiero/aurora";
4
- import { QueryStatus } from "@lookiero/messaging-react";
4
+ import { CommandStatus, QueryStatus } from "@lookiero/messaging-react";
5
5
  import { useLogger } from "@lookiero/sty-psp-logging";
6
6
  import { useScreenSize } from "@lookiero/sty-psp-ui";
7
7
  import { Layout } from "@lookiero/sty-psp-ui";
@@ -11,7 +11,9 @@ import {
11
11
  ProductVariantProjection,
12
12
  } from "../../../../projection/bookedProductsVariants/bookedProductsVariants";
13
13
  import { CheckoutItemProjection } from "../../../../projection/checkoutItem/checkoutItem";
14
+ import { FeedbackProjection } from "../../../../projection/feedback/feedback";
14
15
  import { useBookCheckoutBookingForCheckoutItem } from "../../../domain/checkoutBooking/react/useBookCheckoutBookingForCheckoutItem";
16
+ import { useReturnCheckoutItem } from "../../../domain/checkoutItem/react/useReturnCheckoutItem";
15
17
  import { useViewBookedProductsVariantsForCheckoutItem } from "../../../projection/bookedProductsVariants/react/useViewBookedProductsVariantsForCheckoutItem";
16
18
  import { useViewFirstAvailableCheckoutByCustomerId } from "../../../projection/checkout/react/useViewFirstAvailableCheckoutByCustomerId";
17
19
  import { useViewFiveItemsDiscountByCustomerId } from "../../../projection/checkout/react/useViewFiveItemsDiscountByCustomerId";
@@ -22,14 +24,17 @@ import { useTrackItemPageView } from "../../../tracking/useTrackItemPageView";
22
24
  import { useTrackPressBack } from "../../../tracking/useTrackPressBack";
23
25
  import { useTrackPressNext } from "../../../tracking/useTrackPressNext";
24
26
  import { useTrackPressPrevious } from "../../../tracking/useTrackPressPrevious";
27
+ import { useTrackReturnItem } from "../../../tracking/useTrackReturnItem";
25
28
  import { FiveItemsDiscountBanner } from "../../components/atoms/fiveItemsDiscountBanner/FiveItemsDiscountBanner";
26
29
  import { ReturnQuestionFeedbackProvider } from "../../components/organisms/returnQuestions/behaviors/useReturnQuestionFeedback";
27
30
  import { ItemDetailHeader } from "../../components/templates/header/itemDetailHeader/ItemDetailHeader";
28
31
  import { ItemHeader } from "../../components/templates/header/itemHeader/ItemHeader";
32
+ import { NewFeedbackExperimentVariation, useNewFeedbackExperiment } from "../../hooks/useNewFeedbackExperiment";
29
33
  import { useStaticInfo } from "../../hooks/useStaticInfo";
30
34
  import { Routes } from "../../routing/routes";
31
35
  import { useBasePath } from "../../routing/useBasePath";
32
36
  import { style } from "./Item.style";
37
+ import { ReturnQuestionsForm } from "./components/returnQuestionsForm/ReturnQuestionsForm";
33
38
  import {
34
39
  CheckoutItemWithCustomerDecission,
35
40
  ItemWithCustomerDecission,
@@ -73,6 +78,11 @@ const Item: FC<ItemProps> = ({ layout: Layout }) => {
73
78
  const [checkout, checkoutStatus] = useViewFirstAvailableCheckoutByCustomerId({ customerId });
74
79
  const checkoutItem = checkout?.items.find((checkoutItem) => checkoutItem.id === id) as CheckoutItemProjection;
75
80
 
81
+ /* Kameleoon experiment */
82
+ const newFeedbackVariation = useNewFeedbackExperiment();
83
+ const redirectToReturnPage = newFeedbackVariation === NewFeedbackExperimentVariation.RETURN_PAGE;
84
+ /* Kameleoon experiment */
85
+
76
86
  /* SizeChange and Booking */
77
87
  const [isSizeChangeEnabled, sizeChangeEnabledStatus] = useViewIsSizeChangeEnabledByCheckoutId({
78
88
  checkoutId: checkout?.id,
@@ -101,9 +111,32 @@ const Item: FC<ItemProps> = ({ layout: Layout }) => {
101
111
  const [returnQuestions] = useListReturnQuestionsByCheckoutItemId({
102
112
  checkoutItemId: checkoutItem.id,
103
113
  });
114
+ const [returnQuestionsVisible, setReturnQuestionsVisible] = useState(false);
115
+ const showReturnQuestions = useCallback(() => setReturnQuestionsVisible(true), []);
116
+ const hideReturnQuestions = useCallback(() => setReturnQuestionsVisible(false), []);
104
117
  const goToReturnPage = useCallback(() => {
105
118
  navigate(`${basePath}/${generatePath(Routes.RETURN, { id: checkoutItem.id })}`);
106
119
  }, [basePath, checkoutItem.id, navigate]);
120
+
121
+ const [returnCheckoutItem, returnCheckoutItemStatus] = useReturnCheckoutItem({
122
+ checkoutItemId: checkoutItem.id,
123
+ logger,
124
+ });
125
+ const trackReturnItem = useTrackReturnItem({
126
+ page: TrackingPage.ITEM,
127
+ country,
128
+ segment,
129
+ checkoutId: checkout?.id,
130
+ checkoutItemId: checkoutItem.id,
131
+ });
132
+ const returnItem = useCallback(
133
+ async (feedbacks: FeedbackProjection) => {
134
+ hideReturnQuestions();
135
+ returnCheckoutItem({ feedbacks });
136
+ trackReturnItem();
137
+ },
138
+ [hideReturnQuestions, returnCheckoutItem, trackReturnItem],
139
+ );
107
140
  /* ReturnCheckoutItem */
108
141
 
109
142
  const currentProductVariant: ProductVariantProjection = useMemo(
@@ -209,7 +242,8 @@ const Item: FC<ItemProps> = ({ layout: Layout }) => {
209
242
  bookedProductsVariantsStatus !== QueryStatus.LOADING &&
210
243
  fiveItemsDiscountStatus !== QueryStatus.LOADING &&
211
244
  sizeChangeEnabledStatus !== QueryStatus.LOADING &&
212
- (isBookingRequired ? checkout.checkoutBookingId && bookedProductsVariants : true);
245
+ (isBookingRequired ? checkout.checkoutBookingId && bookedProductsVariants : true) &&
246
+ returnCheckoutItemStatus !== CommandStatus.LOADING;
213
247
 
214
248
  if (!dependenciesLoaded) {
215
249
  return <Spinner testID="spinner" />;
@@ -232,7 +266,7 @@ const Item: FC<ItemProps> = ({ layout: Layout }) => {
232
266
  checkoutId={checkout.id}
233
267
  checkoutItem={checkoutItem as CheckoutItemWithoutCustomerDecission}
234
268
  currentProductVariant={currentProductVariant}
235
- onReturn={goToReturnPage}
269
+ onReturn={redirectToReturnPage ? goToReturnPage : showReturnQuestions}
236
270
  />
237
271
  ) : (
238
272
  <ItemWithCustomerDecission
@@ -240,10 +274,19 @@ const Item: FC<ItemProps> = ({ layout: Layout }) => {
240
274
  checkoutItem={checkoutItem as CheckoutItemWithCustomerDecission}
241
275
  currentProductVariant={currentProductVariant}
242
276
  returnQuestions={returnQuestions}
243
- onEditFeedback={goToReturnPage}
277
+ onEditFeedback={redirectToReturnPage ? goToReturnPage : showReturnQuestions}
244
278
  />
245
279
  )}
246
280
  </Layout>
281
+
282
+ {!redirectToReturnPage ? (
283
+ <ReturnQuestionsForm
284
+ returnQuestions={returnQuestions}
285
+ visible={returnQuestionsVisible}
286
+ onClose={hideReturnQuestions}
287
+ onSubmit={returnItem}
288
+ />
289
+ ) : null}
247
290
  </ReturnQuestionFeedbackProvider>
248
291
  );
249
292
  };
@@ -0,0 +1,18 @@
1
+ import { StyleSheet } from "react-native";
2
+ import { theme } from "@lookiero/sty-psp-ui";
3
+
4
+ const { space6, space8 } = theme();
5
+
6
+ const style = StyleSheet.create({
7
+ modalContent: {
8
+ paddingHorizontal: space6,
9
+ },
10
+ submit: {
11
+ marginTop: space8,
12
+ },
13
+ title: {
14
+ marginBottom: space6,
15
+ },
16
+ });
17
+
18
+ export { style };
@@ -0,0 +1,79 @@
1
+ import { PortalHost } from "@gorhom/portal";
2
+ import React, { FC, useCallback } from "react";
3
+ import { View } from "react-native";
4
+ import { Button, Text } from "@lookiero/aurora";
5
+ import { useI18nMessage } from "@lookiero/i18n-react";
6
+ import { Modal } from "@lookiero/sty-psp-ui";
7
+ import { FeedbackProjection } from "../../../../../../projection/feedback/feedback";
8
+ import {
9
+ ReturnQuestionProjection,
10
+ ReturnQuestionType,
11
+ } from "../../../../../../projection/returnQuestion/returnQuestion";
12
+ import { ReturnQuestions } from "../../../../components/organisms/returnQuestions/ReturnQuestions";
13
+ import { useReturnQuestionFeedback } from "../../../../components/organisms/returnQuestions/behaviors/useReturnQuestionFeedback";
14
+ import {
15
+ ReturnQuestionItemProvider,
16
+ ReturnQuestionItems,
17
+ } from "../../../../components/organisms/returnQuestions/behaviors/useReturnQuestionItem";
18
+ import { HostDefaultReturnQuestionItem } from "../../../../components/organisms/returnQuestions/components/hostDefaultReturnQuestionItem/HostDefaultReturnQuestionItem";
19
+ import { HostSelectReturnQuestionItem } from "../../../../components/organisms/returnQuestions/components/hostSelectReturnQuestionItem/HostSelectReturnQuestionItem";
20
+ import { HostStackReturnQuestionItem } from "../../../../components/organisms/returnQuestions/components/hostStackReturnQuestionItem/modal/HostStackReturnQuestionItem";
21
+ import { OptionReturnQuestionItem } from "../../../../components/organisms/returnQuestions/components/optionReturnQuestionItem/OptionReturnQuestionItem";
22
+ import { TextareaReturnQuestionItem } from "../../../../components/organisms/returnQuestions/components/textareaReturnQuestionItem/TextareaReturnQuestionItem";
23
+ import { I18nMessages } from "../../../../i18n/i18n";
24
+ import { style } from "./ReturnQuestionsForm.style";
25
+
26
+ const RETURN_QUESTION_FORM_PORTAL_HOST_NAME = "return-question-form-portal";
27
+
28
+ const returnQuestionItems: ReturnQuestionItems = {
29
+ [ReturnQuestionType.HOST_DEFAULT]: HostDefaultReturnQuestionItem,
30
+ [ReturnQuestionType.HOST_TEXTAREA]: HostDefaultReturnQuestionItem,
31
+ [ReturnQuestionType.HOST_SELECT]: HostSelectReturnQuestionItem,
32
+ [ReturnQuestionType.HOST_STACK]: HostStackReturnQuestionItem,
33
+ [ReturnQuestionType.TEXTAREA]: TextareaReturnQuestionItem,
34
+ [ReturnQuestionType.OPTION]: OptionReturnQuestionItem,
35
+ };
36
+
37
+ interface ReturnQuestionsFormProps {
38
+ readonly visible: boolean;
39
+ readonly returnQuestions: ReturnQuestionProjection[];
40
+ readonly onSubmit: (feedback: FeedbackProjection) => void;
41
+ readonly onClose: () => void;
42
+ }
43
+
44
+ const ReturnQuestionsForm: FC<ReturnQuestionsFormProps> = ({ returnQuestions, visible, onSubmit, onClose }) => {
45
+ const titleText = useI18nMessage({ id: I18nMessages.RETURN_QUESTIONS_TITLE });
46
+ const submitButtonText = useI18nMessage({ id: I18nMessages.RETURN_QUESTIONS_SUBMIT_BUTTON });
47
+
48
+ const feedback = useReturnQuestionFeedback();
49
+
50
+ const handleOnSubmit = useCallback(() => onSubmit(feedback), [feedback, onSubmit]);
51
+
52
+ return (
53
+ <ReturnQuestionItemProvider returnQuestionItems={returnQuestionItems}>
54
+ <PortalHost name={RETURN_QUESTION_FORM_PORTAL_HOST_NAME} />
55
+ <Modal
56
+ portalHostName={RETURN_QUESTION_FORM_PORTAL_HOST_NAME}
57
+ testID="return-questions-form-modal"
58
+ visible={visible}
59
+ scroll
60
+ showCloseButton
61
+ onClose={onClose}
62
+ >
63
+ <View style={style.modalContent}>
64
+ <Text level={3} style={style.title} heading>
65
+ {titleText}
66
+ </Text>
67
+
68
+ <ReturnQuestions portalHostName={RETURN_QUESTION_FORM_PORTAL_HOST_NAME} returnQuestions={returnQuestions} />
69
+
70
+ <Button style={style.submit} testID="return-questions-button" onPress={handleOnSubmit}>
71
+ {submitButtonText}
72
+ </Button>
73
+ </View>
74
+ </Modal>
75
+ </ReturnQuestionItemProvider>
76
+ );
77
+ };
78
+
79
+ export { ReturnQuestionsForm };
@@ -1,28 +1,216 @@
1
- import React, { FC } from "react";
2
- import { useParams } from "react-router-native";
3
- import { Spinner } from "@lookiero/aurora";
4
- import { QueryStatus } from "@lookiero/messaging-react";
1
+ import { PortalHost } from "@gorhom/portal";
2
+ import React, { FC, useCallback, useMemo } from "react";
3
+ import { ScrollView } from "react-native";
4
+ import { generatePath, useNavigate, useParams } from "react-router-native";
5
+ import { Box, Button, Layout, Spinner, Text, View, useDevice } from "@lookiero/aurora";
6
+ import { useI18nMessage } from "@lookiero/i18n-react";
7
+ import { CommandStatus, QueryStatus } from "@lookiero/messaging-react";
8
+ import { useLogger } from "@lookiero/sty-psp-logging";
9
+ import { Segment } from "@lookiero/sty-psp-segment";
5
10
  import { Layout as UiLayout } from "@lookiero/sty-psp-ui";
11
+ import { CheckoutProjection } from "../../../../projection/checkout/checkout";
6
12
  import { CheckoutItemProjection } from "../../../../projection/checkoutItem/checkoutItem";
13
+ import { FeedbackProjection } from "../../../../projection/feedback/feedback";
14
+ import { ReturnQuestionType } from "../../../../projection/returnQuestion/returnQuestion";
15
+ import { Country } from "../../../../projection/shared/country";
16
+ import { useReturnCheckoutItem } from "../../../domain/checkoutItem/react/useReturnCheckoutItem";
7
17
  import { useViewFirstAvailableCheckoutByCustomerId } from "../../../projection/checkout/react/useViewFirstAvailableCheckoutByCustomerId";
8
- import { ReturnQuestionFeedbackProvider } from "../../components/organisms/returnQuestions/behaviors/useReturnQuestionFeedback";
18
+ import { useListReturnQuestionsByCheckoutItemId } from "../../../projection/returnQuestion/react/useListReturnQuestionsByCheckoutItemId";
19
+ import { TrackingPage } from "../../../tracking/tracking";
20
+ import { useTrackPageView } from "../../../tracking/useTrackPageView";
21
+ import { useTrackPressNext } from "../../../tracking/useTrackPressNext";
22
+ import { useTrackPressPrevious } from "../../../tracking/useTrackPressPrevious";
23
+ import { useTrackReturnItem } from "../../../tracking/useTrackReturnItem";
24
+ import { ReturnQuestions } from "../../components/organisms/returnQuestions/ReturnQuestions";
25
+ import {
26
+ ReturnQuestionFeedbackProvider,
27
+ useReturnQuestionFeedback,
28
+ } from "../../components/organisms/returnQuestions/behaviors/useReturnQuestionFeedback";
29
+ import {
30
+ ReturnQuestionItemProvider,
31
+ ReturnQuestionItems,
32
+ } from "../../components/organisms/returnQuestions/behaviors/useReturnQuestionItem";
33
+ import { HostDefaultReturnQuestionItem } from "../../components/organisms/returnQuestions/components/hostDefaultReturnQuestionItem/HostDefaultReturnQuestionItem";
34
+ import { HostRadioGroupReturnQuestionItem } from "../../components/organisms/returnQuestions/components/hostRadioGroupReturnQuestionItem/HostRadioGroupReturnQuestionItem";
35
+ import { HostStackReturnQuestionItem } from "../../components/organisms/returnQuestions/components/hostStackReturnQuestionItem/form/HostStackReturnQuestionItem";
36
+ import { RadioReturnQuestionItem } from "../../components/organisms/returnQuestions/components/radioReturnQuestionItem/RadioReturnQuestionItem";
37
+ import { TextareaReturnQuestionItem } from "../../components/organisms/returnQuestions/components/textareaReturnQuestionItem/TextareaReturnQuestionItem";
38
+ import { ItemHeader } from "../../components/templates/header/itemHeader/ItemHeader";
9
39
  import { useStaticInfo } from "../../hooks/useStaticInfo";
10
- import { ReturnQuestionsForm } from "./components/returnQuestionsForm/ReturnQuestionsForm";
40
+ import { I18nMessages } from "../../i18n/i18n";
41
+ import { Routes } from "../../routing/routes";
42
+ import { useBasePath } from "../../routing/useBasePath";
43
+ import { style } from "./Return.style";
44
+ import { ProductVariantPreview } from "./components/productVariantPreview/ProductVariantPreview";
45
+
46
+ const returnQuestionItems: ReturnQuestionItems = {
47
+ [ReturnQuestionType.HOST_DEFAULT]: HostDefaultReturnQuestionItem,
48
+ [ReturnQuestionType.HOST_TEXTAREA]: HostDefaultReturnQuestionItem,
49
+ [ReturnQuestionType.HOST_SELECT]: HostRadioGroupReturnQuestionItem,
50
+ [ReturnQuestionType.HOST_STACK]: HostStackReturnQuestionItem,
51
+ [ReturnQuestionType.TEXTAREA]: TextareaReturnQuestionItem,
52
+ [ReturnQuestionType.OPTION]: RadioReturnQuestionItem,
53
+ };
54
+
55
+ interface ReturnFormProps {
56
+ readonly checkoutItem: CheckoutItemProjection;
57
+ readonly country: Country;
58
+ readonly segment: Segment;
59
+ readonly layout: UiLayout;
60
+ readonly checkout: CheckoutProjection;
61
+ }
62
+
63
+ const ReturnForm: FC<ReturnFormProps> = ({ checkout, checkoutItem, country, segment, layout: UiLayout }) => {
64
+ const { screen } = useDevice();
65
+ const navigate = useNavigate();
66
+ const logger = useLogger();
67
+ const basePath = useBasePath();
68
+ const checkoutId = checkout.id;
69
+ const trackPressNext = useTrackPressNext({
70
+ page: TrackingPage.ITEM,
71
+ country,
72
+ segment,
73
+ checkoutId,
74
+ });
75
+ const trackPressPrevious = useTrackPressPrevious({
76
+ page: TrackingPage.ITEM,
77
+ country,
78
+ segment,
79
+ checkoutId,
80
+ });
81
+ const titleText = useI18nMessage({ id: I18nMessages.RETURN_QUESTIONS_TITLE });
82
+ const descriptionText = useI18nMessage({ id: I18nMessages.RETURN_QUESTIONS_DESCRIPTION });
83
+ const submitButtonText = useI18nMessage({ id: I18nMessages.RETURN_QUESTIONS_SUBMIT_BUTTON });
84
+ const isSmallScreen = screen.S;
85
+
86
+ useTrackPageView({ checkoutId, country, segment, page: TrackingPage.RETURN });
87
+
88
+ /* ReturnCheckoutItem */
89
+ const [returnQuestions] = useListReturnQuestionsByCheckoutItemId({
90
+ checkoutItemId: checkoutItem.id,
91
+ });
92
+
93
+ const [returnCheckoutItem, returnCheckoutItemStatus] = useReturnCheckoutItem({
94
+ checkoutItemId: checkoutItem.id,
95
+ logger,
96
+ });
97
+ const trackReturnItem = useTrackReturnItem({
98
+ page: TrackingPage.RETURN,
99
+ country,
100
+ segment,
101
+ checkoutId: checkoutId,
102
+ checkoutItemId: checkoutItem.id,
103
+ });
104
+
105
+ const navigateToNextItem = useCallback(() => {
106
+ const item = checkoutItem;
107
+ const items = checkout?.items as CheckoutItemProjection[];
108
+ const itemIndex = items.indexOf(item);
109
+ const nextItemIndex = itemIndex === items.length - 1 ? 0 : itemIndex + 1;
110
+ const nextItem = items[nextItemIndex] as CheckoutItemProjection;
111
+
112
+ trackPressNext({ from: item.id, to: nextItem.id });
113
+ navigate(generatePath(`${basePath}/${Routes.ITEM}`, { id: nextItem.id }));
114
+ }, [basePath, checkout?.items, checkoutItem, navigate, trackPressNext]);
115
+
116
+ const navigateToPreviousItem = useCallback(() => {
117
+ const item = checkoutItem;
118
+ const items = checkout?.items as CheckoutItemProjection[];
119
+ const itemIndex = items.indexOf(item);
120
+ const previousItemIndex = itemIndex === 0 ? items.length - 1 : itemIndex - 1;
121
+ const previousItem = items[previousItemIndex] as CheckoutItemProjection;
122
+
123
+ trackPressPrevious({ from: item.id, to: previousItem.id });
124
+
125
+ navigate(generatePath(`${basePath}/${Routes.ITEM}`, { id: previousItem.id }));
126
+ }, [basePath, checkout?.items, checkoutItem, navigate, trackPressPrevious]);
127
+
128
+ const returnItem = useCallback(
129
+ async (feedbacks: FeedbackProjection) => {
130
+ returnCheckoutItem({ feedbacks });
131
+ trackReturnItem();
132
+ navigateToNextItem();
133
+ },
134
+ [navigateToNextItem, returnCheckoutItem, trackReturnItem],
135
+ );
136
+
137
+ const feedback = useReturnQuestionFeedback();
138
+
139
+ const handleOnSubmit = useCallback(() => returnItem(feedback), [feedback, returnItem]);
140
+
141
+ const header = useMemo(
142
+ () => (
143
+ <Box style={style.headerWrapper}>
144
+ <ItemHeader
145
+ item={checkoutItem}
146
+ items={checkout?.items as CheckoutItemProjection[]}
147
+ onNext={navigateToNextItem}
148
+ onPrevious={navigateToPreviousItem}
149
+ />
150
+ </Box>
151
+ ),
152
+ [checkout?.items, checkoutItem, navigateToNextItem, navigateToPreviousItem],
153
+ );
154
+
155
+ /* ReturnCheckoutItem */
156
+
157
+ const dependenciesLoaded = checkoutItem && returnQuestions && returnCheckoutItemStatus !== CommandStatus.LOADING;
158
+
159
+ if (!dependenciesLoaded) {
160
+ return <Spinner />;
161
+ }
162
+
163
+ return (
164
+ <ReturnQuestionItemProvider returnQuestionItems={returnQuestionItems}>
165
+ <PortalHost name="return-question-form-portal" />
166
+ <UiLayout
167
+ header={header}
168
+ scrollEnabled={false}
169
+ style={{
170
+ safeAreaView: style.safeAreaView,
171
+ scrollView: style.scrollView,
172
+ }}
173
+ >
174
+ <ProductVariantPreview country={country} item={checkoutItem} />
175
+
176
+ <ScrollView showsVerticalScrollIndicator={false}>
177
+ <Layout fullWidth={!screen.L} style={[style.layout, screen.L ? style.desktopLayoutSpacing : undefined]}>
178
+ <Box size={{ L: "2/3" }}>
179
+ <View style={[style.info, isSmallScreen ? undefined : style.desktopInfo]}>
180
+ <Text level={3} heading>
181
+ {titleText}
182
+ </Text>
183
+ <Text level={1} style={style.description} detail>
184
+ {descriptionText}
185
+ </Text>
186
+ </View>
187
+
188
+ <ReturnQuestions portalHostName="return-question-form-portal" returnQuestions={returnQuestions} />
189
+
190
+ <View style={style.submit}>
191
+ <Button testID="return-questions-button" onPress={handleOnSubmit}>
192
+ {submitButtonText}
193
+ </Button>
194
+ </View>
195
+ </Box>
196
+ </Layout>
197
+ </ScrollView>
198
+ </UiLayout>
199
+ </ReturnQuestionItemProvider>
200
+ );
201
+ };
11
202
 
12
203
  interface ReturnProps {
13
204
  readonly layout: UiLayout;
14
205
  }
15
206
 
16
- const Return: FC<ReturnProps> = ({ layout }) => {
207
+ const Return: FC<ReturnProps> = ({ layout: UiLayout }) => {
17
208
  const { id } = useParams();
18
209
  const {
19
210
  customer: { customerId, country, segment },
20
211
  } = useStaticInfo();
21
-
22
212
  const [checkout, checkoutStatus] = useViewFirstAvailableCheckoutByCustomerId({ customerId });
23
-
24
213
  const checkoutItem = checkout?.items.find((checkoutItem) => checkoutItem.id === id) as CheckoutItemProjection;
25
-
26
214
  const dependenciesLoaded = checkoutStatus !== QueryStatus.LOADING && checkout && checkoutItem;
27
215
 
28
216
  if (!dependenciesLoaded) {
@@ -31,11 +219,11 @@ const Return: FC<ReturnProps> = ({ layout }) => {
31
219
 
32
220
  return (
33
221
  <ReturnQuestionFeedbackProvider key={checkoutItem.id} feedback={checkoutItem.feedbacks || {}}>
34
- <ReturnQuestionsForm
222
+ <ReturnForm
35
223
  checkout={checkout}
36
224
  checkoutItem={checkoutItem}
37
225
  country={country}
38
- layout={layout}
226
+ layout={UiLayout}
39
227
  segment={segment}
40
228
  />
41
229
  </ReturnQuestionFeedbackProvider>
@@ -19,22 +19,19 @@ interface ProductVariantPreviewProps {
19
19
  const ProductVariantPreview: FC<ProductVariantPreviewProps> = ({ item, country }) => {
20
20
  const cdnImageUrl = useMediaImage();
21
21
  const { screen } = useDevice();
22
+ const isSmallScreen = screen.S;
23
+ const { productVariant, price } = item;
24
+ const { media, brand, name, size: sizeProjection } = productVariant;
25
+ const mainImage = media.find((mediaElement) => mediaElement.perspective === "MAIN");
22
26
 
23
27
  const sizeText = useI18nMessage({ id: I18nMessages.ITEM_SIZE });
24
28
  const uniqueText = useI18nMessage({ id: I18nMessages.ITEM_UNIQUE });
25
29
 
26
- const {
27
- productVariant: { media, brand, name, size: sizeProjection },
28
- price,
29
- } = item;
30
-
31
- const mainImage = media.find((mediaElement) => mediaElement.perspective === "MAIN");
32
-
33
30
  return (
34
- <View style={[style.wrapper, !screen.S && style.mobileWrapper]} testID="product-variant-preview">
31
+ <View style={[style.wrapper, isSmallScreen ? style.mobileWrapper : undefined]}>
35
32
  <Row style={style.row}>
36
33
  <Column size={{ M: "2/3", L: "2/3" }} style={style.content}>
37
- {mainImage && (
34
+ {mainImage ? (
38
35
  <Image
39
36
  resizeMode="stretch"
40
37
  style={style.image}
@@ -46,8 +43,7 @@ const ProductVariantPreview: FC<ProductVariantPreviewProps> = ({ item, country }
46
43
  }),
47
44
  }}
48
45
  />
49
- )}
50
-
46
+ ) : null}
51
47
  <View style={style.info}>
52
48
  <Text color={COLOR.TEXT_MEDIUM} level={2} detail>
53
49
  {brand}
@@ -59,7 +55,6 @@ const ProductVariantPreview: FC<ProductVariantPreviewProps> = ({ item, country }
59
55
  {`${sizeText} ${sizeProjection.unique ? uniqueText : size({ size: sizeProjection, country })}`}
60
56
  </Text>
61
57
  </View>
62
-
63
58
  <View style={style.price}>
64
59
  <Price price={price} withPercentage />
65
60
  </View>
@@ -1,7 +1,7 @@
1
1
  import React, { FC, ReactNode, useCallback, useEffect, useMemo, useState } from "react";
2
2
  import { LayoutRectangle, Platform, ScrollView, View } from "react-native";
3
3
  import { generatePath, useMatch, useNavigate } from "react-router-native";
4
- import { Box, Text, Layout as AuroraLayout, useDevice, Spinner } from "@lookiero/aurora";
4
+ import { Box, Text, Layout, useDevice, Spinner } from "@lookiero/aurora";
5
5
  import { useI18nMessage } from "@lookiero/i18n-react";
6
6
  import { QueryStatus } from "@lookiero/messaging-react";
7
7
  import { Layout as UiLayout, Sticky } from "@lookiero/sty-psp-ui";
@@ -27,7 +27,7 @@ interface SummaryProps {
27
27
  readonly children: ReactNode;
28
28
  }
29
29
 
30
- const Summary: FC<SummaryProps> = ({ layout: Layout, children }) => {
30
+ const Summary: FC<SummaryProps> = ({ layout: UiLayout, children }) => {
31
31
  const {
32
32
  customer: { customerId, country, segment },
33
33
  } = useStaticInfo();
@@ -110,7 +110,7 @@ const Summary: FC<SummaryProps> = ({ layout: Layout, children }) => {
110
110
  }
111
111
 
112
112
  return (
113
- <Layout
113
+ <UiLayout
114
114
  scrollEnabled={false}
115
115
  style={{
116
116
  header: style.header,
@@ -120,7 +120,7 @@ const Summary: FC<SummaryProps> = ({ layout: Layout, children }) => {
120
120
  <ScrollView showsVerticalScrollIndicator={false}>
121
121
  {fiveItemsDiscount !== 0 && <FiveItemsDiscountBanner fiveItemsDiscount={fiveItemsDiscount} />}
122
122
 
123
- <AuroraLayout
123
+ <Layout
124
124
  fullWidth={!screen.L}
125
125
  style={[screen.L && style.desktopLayoutSpacing, !screen.L && { paddingBottom: pricingHeight }]}
126
126
  >
@@ -153,7 +153,7 @@ const Summary: FC<SummaryProps> = ({ layout: Layout, children }) => {
153
153
  </View>
154
154
  </Box>
155
155
  ) : null}
156
- </AuroraLayout>
156
+ </Layout>
157
157
  </ScrollView>
158
158
 
159
159
  {pricing && !screen.L ? (
@@ -170,7 +170,7 @@ const Summary: FC<SummaryProps> = ({ layout: Layout, children }) => {
170
170
  </Body>
171
171
  </Sticky>
172
172
  ) : null}
173
- </Layout>
173
+ </UiLayout>
174
174
  );
175
175
  };
176
176
 
@@ -1,15 +0,0 @@
1
- import { FC } from "react";
2
- import { Segment } from "@lookiero/sty-psp-segment";
3
- import { Layout as UiLayout } from "@lookiero/sty-psp-ui";
4
- import { CheckoutProjection } from "../../../../../../projection/checkout/checkout";
5
- import { CheckoutItemProjection } from "../../../../../../projection/checkoutItem/checkoutItem";
6
- import { Country } from "../../../../../../projection/shared/country";
7
- interface ReturnQuestionsFormProps {
8
- readonly checkout: CheckoutProjection;
9
- readonly checkoutItem: CheckoutItemProjection;
10
- readonly country: Country;
11
- readonly layout: UiLayout;
12
- readonly segment: Segment;
13
- }
14
- declare const ReturnQuestionsForm: FC<ReturnQuestionsFormProps>;
15
- export { ReturnQuestionsForm };