@lookiero/checkout 3.7.0 → 3.8.0-beta.1

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 (95) hide show
  1. package/dist/domain/checkoutBooking/event/createNotificationWhenCheckoutBookingExpired.d.ts +6 -0
  2. package/dist/domain/checkoutBooking/event/createNotificationWhenCheckoutBookingExpired.js +13 -0
  3. package/dist/infrastructure/domain/uiSetting/react/useIncrementIntroShownCount.d.ts +10 -0
  4. package/dist/infrastructure/domain/uiSetting/react/useIncrementIntroShownCount.js +11 -0
  5. package/dist/infrastructure/projection/uiSetting/react/useShouldIntroBeShown.d.ts +6 -0
  6. package/dist/infrastructure/projection/uiSetting/react/useShouldIntroBeShown.js +7 -0
  7. package/dist/infrastructure/projection/uiSetting/react/useViewIntroShownCount.d.ts +6 -0
  8. package/dist/infrastructure/projection/uiSetting/react/useViewIntroShownCount.js +9 -0
  9. package/dist/infrastructure/ui/components/organisms/checkoutQuestions/CheckoutQuestion.js +1 -1
  10. package/dist/infrastructure/ui/components/organisms/checkoutQuestions/components/CheckoutQuestionItem.d.ts +1 -0
  11. package/dist/infrastructure/ui/components/organisms/checkoutQuestions/components/buttonCheckoutQuestionItem/ButtonCheckoutQuestionItem.js +2 -2
  12. package/dist/infrastructure/ui/components/organisms/checkoutQuestions/components/iconCheckoutQuestionItem/IconCheckoutQuestionItem.js +3 -3
  13. package/dist/infrastructure/ui/components/organisms/checkoutQuestions/components/textareaCheckoutQuestionItem/TextareaCheckoutQuestionItem.js +2 -2
  14. package/dist/infrastructure/ui/components/organisms/returnQuestions/ReturnQuestion.js +1 -1
  15. package/dist/infrastructure/ui/components/organisms/returnQuestions/components/ReturnQuestionItem.d.ts +1 -0
  16. package/dist/infrastructure/ui/components/organisms/returnQuestions/components/hostSelectReturnQuestionItem/HostSelectReturnQuestionItem.js +2 -2
  17. package/dist/infrastructure/ui/components/organisms/returnQuestions/components/optionReturnQuestionItem/OptionReturnQuestionItem.js +2 -2
  18. package/dist/infrastructure/ui/components/organisms/returnQuestions/components/textareaReturnQuestionItem/TextareaReturnQuestionItem.js +2 -2
  19. package/dist/infrastructure/ui/components/templates/SafeAreaScrollView.d.ts +13 -0
  20. package/dist/infrastructure/ui/components/templates/SafeAreaScrollView.js +19 -0
  21. package/dist/infrastructure/ui/components/templates/SafeAreaScrollView.style.ts.d.ts +6 -0
  22. package/dist/infrastructure/ui/components/templates/SafeAreaScrollView.style.ts.js +7 -0
  23. package/dist/infrastructure/ui/components/templates/header/header/Header.d.ts +3 -0
  24. package/dist/infrastructure/ui/components/templates/header/header/Header.js +10 -0
  25. package/dist/infrastructure/ui/components/templates/header/header/Header.style.d.ts +9 -0
  26. package/dist/infrastructure/ui/components/templates/header/header/Header.style.js +12 -0
  27. package/dist/infrastructure/ui/components/templates/safeAreaScrollView/SafeAreaScrollView.d.ts +13 -0
  28. package/dist/infrastructure/ui/components/templates/safeAreaScrollView/SafeAreaScrollView.js +19 -0
  29. package/dist/infrastructure/ui/components/templates/safeAreaScrollView/SafeAreaScrollView.style.ts.d.ts +6 -0
  30. package/dist/infrastructure/ui/components/templates/safeAreaScrollView/SafeAreaScrollView.style.ts.js +7 -0
  31. package/dist/infrastructure/ui/hooks/usePaymentInstrumentUpdateEvents.d.ts +2 -0
  32. package/dist/infrastructure/ui/hooks/usePaymentInstrumentUpdateEvents.js +28 -0
  33. package/dist/infrastructure/ui/hooks/useToast.d.ts +11 -0
  34. package/dist/infrastructure/ui/hooks/useToast.js +49 -0
  35. package/dist/infrastructure/ui/views/checkout/components/checkoutSuccessModal/CheckoutSuccessModal.d.ts +7 -0
  36. package/dist/infrastructure/ui/views/checkout/components/checkoutSuccessModal/CheckoutSuccessModal.js +25 -0
  37. package/dist/infrastructure/ui/views/checkout/components/checkoutSuccessModal/CheckoutSuccessModal.style.d.ts +16 -0
  38. package/dist/infrastructure/ui/views/checkout/components/checkoutSuccessModal/CheckoutSuccessModal.style.js +19 -0
  39. package/dist/infrastructure/ui/views/feedback/components/checkoutQuestionsForm/CheckoutQuestionsForm.js +1 -1
  40. package/dist/infrastructure/ui/views/intro/Intro.d.ts +6 -0
  41. package/dist/infrastructure/ui/views/intro/Intro.js +52 -0
  42. package/dist/infrastructure/ui/views/intro/Intro.style.d.ts +52 -0
  43. package/dist/infrastructure/ui/views/intro/Intro.style.js +55 -0
  44. package/dist/infrastructure/ui/views/item/Item.style.d.ts +15 -0
  45. package/dist/infrastructure/ui/views/item/Item.style.js +18 -0
  46. package/dist/infrastructure/ui/views/item/components/itemActions/ItemActions.js +2 -2
  47. package/dist/infrastructure/ui/views/item/components/productVariant/ProductVariant.d.ts +26 -0
  48. package/dist/infrastructure/ui/views/item/components/productVariant/ProductVariant.js +44 -0
  49. package/dist/infrastructure/ui/views/item/components/productVariant/ProductVariant.style.d.ts +45 -0
  50. package/dist/infrastructure/ui/views/item/components/productVariant/ProductVariant.style.js +53 -0
  51. package/dist/infrastructure/ui/views/item/components/returnQuestionsForm/ReturnQuestionsForm.js +1 -1
  52. package/dist/infrastructure/ui/views/item/components/sizeChangeModal/SizeChangeModal.d.ts +7 -0
  53. package/dist/infrastructure/ui/views/item/components/sizeChangeModal/SizeChangeModal.js +25 -0
  54. package/dist/infrastructure/ui/views/item/components/sizeChangeModal/SizeChangeModal.style.d.ts +16 -0
  55. package/dist/infrastructure/ui/views/item/components/sizeChangeModal/SizeChangeModal.style.js +19 -0
  56. package/dist/infrastructure/ui/views/navigation/Navigation.d.ts +21 -0
  57. package/dist/infrastructure/ui/views/navigation/Navigation.js +45 -0
  58. package/dist/infrastructure/ui/views/navigation/Navigation.style.d.ts +5 -0
  59. package/dist/infrastructure/ui/views/navigation/Navigation.style.js +30 -0
  60. package/dist/infrastructure/ui/views/navigation/components/header/Header.d.ts +46 -0
  61. package/dist/infrastructure/ui/views/navigation/components/header/Header.js +120 -0
  62. package/dist/infrastructure/ui/views/navigation/components/header/Header.style.d.ts +31 -0
  63. package/dist/infrastructure/ui/views/navigation/components/header/Header.style.js +34 -0
  64. package/dist/infrastructure/ui/views/navigation/components/header/Logo.d.ts +7 -0
  65. package/dist/infrastructure/ui/views/navigation/components/header/Logo.js +11 -0
  66. package/dist/infrastructure/ui/views/navigation/components/header/Logo.style.d.ts +7 -0
  67. package/dist/infrastructure/ui/views/navigation/components/header/Logo.style.js +8 -0
  68. package/dist/infrastructure/ui/views/summary/components/checkoutItemsTabs/CheckoutItemsTabs.d.ts +12 -0
  69. package/dist/infrastructure/ui/views/summary/components/checkoutItemsTabs/CheckoutItemsTabs.js +24 -0
  70. package/dist/infrastructure/ui/views/summary/components/checkoutItemsTabs/CheckoutItemsTabs.style.d.ts +15 -0
  71. package/dist/infrastructure/ui/views/summary/components/checkoutItemsTabs/CheckoutItemsTabs.style.js +18 -0
  72. package/dist/infrastructure/ui/views/summary/components/pricing/Pricing.js +2 -2
  73. package/dist/shared/notifications/domain/notification/command/createNotification.d.ts +17 -0
  74. package/dist/shared/notifications/domain/notification/command/createNotification.js +7 -0
  75. package/dist/shared/notifications/infrastructure/domain/notification/react/useCreateNotification.d.ts +21 -0
  76. package/dist/shared/notifications/infrastructure/domain/notification/react/useCreateNotification.js +22 -0
  77. package/dist/shared/notifications/infrastructure/ui/components/NotificationItem.d.ts +12 -0
  78. package/dist/shared/notifications/infrastructure/ui/components/NotificationItem.js +24 -0
  79. package/dist/shared/notifications/infrastructure/ui/components/Notifications.d.ts +9 -0
  80. package/dist/shared/notifications/infrastructure/ui/components/Notifications.js +20 -0
  81. package/dist/shared/notifications/infrastructure/ui/components/Notifications.style.d.ts +36 -0
  82. package/dist/shared/notifications/infrastructure/ui/components/Notifications.style.js +31 -0
  83. package/dist/shared/notifications/infrastructure/ui/components/modalNotifications/ModalNotificationItem.js +1 -1
  84. package/dist/shared/tracking/infrastructure/usePageView.d.ts +13 -0
  85. package/dist/shared/tracking/infrastructure/usePageView.js +27 -0
  86. package/dist/shared/ui/components/atoms/error/Error.style.d.ts +6 -0
  87. package/dist/shared/ui/components/atoms/error/Error.style.js +9 -0
  88. package/dist/shared/ui/components/atoms/input/Input.js +2 -2
  89. package/dist/shared/ui/components/layouts/modal/Modal.js +1 -1
  90. package/dist/shared/ui/components/layouts/slider/Pagination.d.ts +14 -0
  91. package/dist/shared/ui/components/layouts/slider/Pagination.js +11 -0
  92. package/dist/shared/ui/components/layouts/slider/Pagination.style.d.ts +23 -0
  93. package/dist/shared/ui/components/layouts/slider/Pagination.style.js +27 -0
  94. package/dist/shared/ui/components/molecules/selectField/SelectField.js +3 -3
  95. package/package.json +1 -1
@@ -0,0 +1,6 @@
1
+ import { ProcessManagerFunction } from "@lookiero/messaging";
2
+ import { CheckoutBookingExpired } from "../model/checkoutBookingExpired";
3
+ interface CreateNotificationWhenCheckoutBookingExpiredFunction extends ProcessManagerFunction<CheckoutBookingExpired> {
4
+ }
5
+ declare const createNotificationWhenCheckoutBookingExpired: CreateNotificationWhenCheckoutBookingExpiredFunction;
6
+ export { createNotificationWhenCheckoutBookingExpired };
@@ -0,0 +1,13 @@
1
+ import { v4 as uuid } from "uuid";
2
+ import { I18nMessages } from "../../../infrastructure/ui/i18n/i18n";
3
+ import { createNotification } from "../../../shared/notifications/domain/notification/command/createNotification";
4
+ import { NotificationLevel } from "../../../shared/notifications/domain/notification/model/notification";
5
+ const createNotificationWhenCheckoutBookingExpired = ({ commandBus }) => async () => {
6
+ await commandBus(createNotification({
7
+ aggregateId: uuid(),
8
+ level: NotificationLevel.ERROR,
9
+ titleI18nKey: undefined,
10
+ bodyI18nKey: I18nMessages.CHECKOUT_TOAST_BOOKING_EXPIRED,
11
+ }));
12
+ };
13
+ export { createNotificationWhenCheckoutBookingExpired };
@@ -0,0 +1,10 @@
1
+ import { CommandStatus } from "@lookiero/messaging-react";
2
+ interface IncrementIntroShownCountFunction {
3
+ (): Promise<void>;
4
+ }
5
+ type UseIncrementIntroShownCount = [incrementIntroShownCount: IncrementIntroShownCountFunction, status: CommandStatus];
6
+ interface UseIncrementIntroShownCountFunction {
7
+ (): UseIncrementIntroShownCount;
8
+ }
9
+ declare const useIncrementIntroShownCount: UseIncrementIntroShownCountFunction;
10
+ export { useIncrementIntroShownCount };
@@ -0,0 +1,11 @@
1
+ import { useCallback } from "react";
2
+ import { useViewIntroShownCount } from "../../../projection/uiSetting/react/useViewIntroShownCount";
3
+ import { UISettings } from "../../../ui/settings/UISettings";
4
+ import { useUpdateUiSetting } from "./useUpdateUiSetting";
5
+ const useIncrementIntroShownCount = () => {
6
+ const [update, status] = useUpdateUiSetting();
7
+ const [introShownCount] = useViewIntroShownCount();
8
+ const incrementIntroShownCount = useCallback(() => update({ key: UISettings.INTRO_SHOWN_COUNT, value: introShownCount + 1 }), [introShownCount, update]);
9
+ return [incrementIntroShownCount, status];
10
+ };
11
+ export { useIncrementIntroShownCount };
@@ -0,0 +1,6 @@
1
+ import { QueryStatus } from "@lookiero/messaging-react";
2
+ interface UseShouldIntroBeShownFunction {
3
+ (): [boolean, QueryStatus];
4
+ }
5
+ declare const useShouldIntroBeShown: UseShouldIntroBeShownFunction;
6
+ export { useShouldIntroBeShown };
@@ -0,0 +1,7 @@
1
+ import { useViewIntroShownCount } from "./useViewIntroShownCount";
2
+ const MAX_INTRO_SHOWN_COUNT = 2;
3
+ const useShouldIntroBeShown = () => {
4
+ const [introShownCount, introShownCountStatus] = useViewIntroShownCount();
5
+ return [introShownCount < MAX_INTRO_SHOWN_COUNT, introShownCountStatus];
6
+ };
7
+ export { useShouldIntroBeShown };
@@ -0,0 +1,6 @@
1
+ import { QueryStatus } from "@lookiero/messaging-react";
2
+ interface UseViewIntroShownCountFunction {
3
+ (): [number, QueryStatus];
4
+ }
5
+ declare const useViewIntroShownCount: UseViewIntroShownCountFunction;
6
+ export { useViewIntroShownCount };
@@ -0,0 +1,9 @@
1
+ import { UISettings } from "../../../ui/settings/UISettings";
2
+ import { useViewUiSettingByKey } from "./useViewUiSettingByKey";
3
+ const useViewIntroShownCount = () => {
4
+ const [introShownCount, introShownCountStatus] = useViewUiSettingByKey({
5
+ key: UISettings.INTRO_SHOWN_COUNT,
6
+ });
7
+ return [introShownCount?.value || 0, introShownCountStatus];
8
+ };
9
+ export { useViewIntroShownCount };
@@ -2,7 +2,7 @@ import React, { memo } from "react";
2
2
  import { useCheckoutQuestionItem } from "./behaviors/useCheckoutQuestionItem";
3
3
  const CheckoutQuestion = ({ checkoutQuestion, checkoutQuestionParentId, }) => {
4
4
  const Item = useCheckoutQuestionItem({ type: checkoutQuestion.type });
5
- return (React.createElement(Item, { checkoutQuestion: checkoutQuestion, checkoutQuestionParentId: checkoutQuestionParentId },
5
+ return (React.createElement(Item, { checkoutQuestion: checkoutQuestion, checkoutQuestionParentId: checkoutQuestionParentId, testID: checkoutQuestion.id },
6
6
  React.createElement(React.Fragment, null, checkoutQuestion.children?.map((childCheckoutQuestion) => (React.createElement(CheckoutQuestion, { key: childCheckoutQuestion.id, checkoutQuestion: childCheckoutQuestion, checkoutQuestionParentId: checkoutQuestion.id }))))));
7
7
  };
8
8
  export default memo(CheckoutQuestion);
@@ -5,6 +5,7 @@ interface CheckoutQuestionItemProps {
5
5
  readonly checkoutQuestionParentId: string;
6
6
  readonly children?: ReactNode;
7
7
  readonly portalHostName?: string;
8
+ readonly testID: string;
8
9
  }
9
10
  type CheckoutQuestionItem = FC<CheckoutQuestionItemProps>;
10
11
  export type { CheckoutQuestionItem, CheckoutQuestionItemProps };
@@ -5,10 +5,10 @@ import { theme } from "../../../../../theme/theme";
5
5
  import { useCheckoutQuestionFeedbackForId } from "../../behaviors/useCheckoutQuestionFeedback";
6
6
  import { style } from "./ButtonCheckoutQuestionItem.style";
7
7
  const { colorAccent, colorBase } = theme();
8
- const ButtonCheckoutQuestionItem = ({ checkoutQuestion, checkoutQuestionParentId, }) => {
8
+ const ButtonCheckoutQuestionItem = ({ checkoutQuestion, checkoutQuestionParentId, testID, }) => {
9
9
  const { feedback, onChange } = useCheckoutQuestionFeedbackForId({ id: checkoutQuestionParentId });
10
10
  const optionText = useI18nMessage({ id: checkoutQuestion.name });
11
11
  const handleOnPress = useCallback(() => onChange({ checkoutQuestionId: checkoutQuestionParentId, checkoutQuestionFeedback: checkoutQuestion.id }), [onChange, checkoutQuestion.id, checkoutQuestionParentId]);
12
- return (React.createElement(Button, { style: [style.button, { backgroundColor: feedback === checkoutQuestion.id ? colorAccent : colorBase }], variant: BUTTON_VARIANT.SECONDARY, onPress: handleOnPress }, optionText));
12
+ return (React.createElement(Button, { accessibilityLabel: testID, style: [style.button, { backgroundColor: feedback === checkoutQuestion.id ? colorAccent : colorBase }], testID: testID, variant: BUTTON_VARIANT.SECONDARY, onPress: handleOnPress }, optionText));
13
13
  };
14
14
  export { ButtonCheckoutQuestionItem };
@@ -16,12 +16,12 @@ const ICON = {
16
16
  // eslint-disable-next-line @typescript-eslint/naming-convention
17
17
  "checkout_question.icon.good": Happy,
18
18
  };
19
- const IconCheckoutQuestionItem = ({ checkoutQuestion, checkoutQuestionParentId, }) => {
19
+ const IconCheckoutQuestionItem = ({ checkoutQuestion, checkoutQuestionParentId, testID, }) => {
20
20
  const Icon = ICON[checkoutQuestion.name];
21
21
  const { feedback, onChange } = useCheckoutQuestionFeedbackForId({ id: checkoutQuestionParentId });
22
22
  const handleOnPress = useCallback(() => onChange({ checkoutQuestionId: checkoutQuestionParentId, checkoutQuestionFeedback: checkoutQuestion.id }), [onChange, checkoutQuestion.id, checkoutQuestionParentId]);
23
23
  invariant(Icon, "CheckoutQuestion icon does not exist");
24
- return (React.createElement(Pressable, { onPress: handleOnPress },
25
- React.createElement(Icon, { fill: feedback === checkoutQuestion.id ? colorAccent : "none", style: style.icon, testID: checkoutQuestion.name })));
24
+ return (React.createElement(Pressable, { accessibilityLabel: testID, testID: testID, onPress: handleOnPress },
25
+ React.createElement(Icon, { fill: feedback === checkoutQuestion.id ? colorAccent : "none", style: style.icon })));
26
26
  };
27
27
  export { IconCheckoutQuestionItem };
@@ -3,11 +3,11 @@ import React, { useCallback, useMemo } from "react";
3
3
  import { InputField } from "../../../../../../../shared/ui/components/molecules/inputField/InputField";
4
4
  import { useCheckoutQuestionFeedbackForId } from "../../behaviors/useCheckoutQuestionFeedback";
5
5
  const TEXTAREA_MIN_HEIGHT = 96;
6
- const TextareaCheckoutQuestionItem = ({ checkoutQuestion, checkoutQuestionParentId, }) => {
6
+ const TextareaCheckoutQuestionItem = ({ checkoutQuestion, checkoutQuestionParentId, testID, }) => {
7
7
  const { formatMessage } = useIntl();
8
8
  const placeholderText = useMemo(() => (checkoutQuestion.placeholder ? formatMessage({ id: checkoutQuestion.placeholder }) : ""), [formatMessage, checkoutQuestion.placeholder]);
9
9
  const { feedback, onChange } = useCheckoutQuestionFeedbackForId({ id: checkoutQuestionParentId });
10
10
  const handleOnChange = useCallback((value) => onChange({ checkoutQuestionId: checkoutQuestionParentId, checkoutQuestionFeedback: value }), [onChange, checkoutQuestionParentId]);
11
- return (React.createElement(InputField, { label: placeholderText, minHeight: TEXTAREA_MIN_HEIGHT, placeholder: placeholderText, value: feedback, multiline: true, onChange: handleOnChange }));
11
+ return (React.createElement(InputField, { label: placeholderText, minHeight: TEXTAREA_MIN_HEIGHT, placeholder: placeholderText, testID: testID, value: feedback, multiline: true, onChange: handleOnChange }));
12
12
  };
13
13
  export { TextareaCheckoutQuestionItem };
@@ -2,7 +2,7 @@ import React, { memo } from "react";
2
2
  import { useReturnQuestionItem } from "./behaviors/useReturnQuestionItem";
3
3
  const ReturnQuestion = ({ returnQuestion, returnQuestionParentId, portalHostName, }) => {
4
4
  const Item = useReturnQuestionItem({ type: returnQuestion.type });
5
- return (React.createElement(Item, { portalHostName: portalHostName, returnQuestion: returnQuestion, returnQuestionParentId: returnQuestionParentId },
5
+ return (React.createElement(Item, { portalHostName: portalHostName, returnQuestion: returnQuestion, returnQuestionParentId: returnQuestionParentId, testID: returnQuestion.id },
6
6
  React.createElement(React.Fragment, null, returnQuestion.children?.map((childReturnQuestion) => (React.createElement(ReturnQuestion, { key: childReturnQuestion.id, portalHostName: portalHostName, returnQuestion: childReturnQuestion, returnQuestionParentId: returnQuestion.id }))))));
7
7
  };
8
8
  export default memo(ReturnQuestion);
@@ -5,6 +5,7 @@ interface ReturnQuestionItemProps {
5
5
  readonly returnQuestionParentId: string;
6
6
  readonly children?: ReactNode;
7
7
  readonly portalHostName?: string;
8
+ readonly testID: string;
8
9
  }
9
10
  type ReturnQuestionItem = FC<ReturnQuestionItemProps>;
10
11
  export type { ReturnQuestionItem, ReturnQuestionItemProps };
@@ -7,7 +7,7 @@ import { InputField } from "../../../../../../../shared/ui/components/molecules/
7
7
  import { useReturnQuestionFeedback, useReturnQuestionFeedbackForId } from "../../behaviors/useReturnQuestionFeedback";
8
8
  import { deepestReturnQuestionWithFeedbackForReturnQuestion, feedbackForReturnQuestion, } from "../../util/returnQuestionFeedback";
9
9
  import { style, containerUnderlayColor } from "./HostSelectReturnQuestionItem.style";
10
- const HostSelectReturnQuestionItem = ({ returnQuestion, children, portalHostName, }) => {
10
+ const HostSelectReturnQuestionItem = ({ returnQuestion, children, portalHostName, testID, }) => {
11
11
  const { formatMessage } = useIntl();
12
12
  const placeholderText = useMemo(() => (returnQuestion.placeholder ? formatMessage({ id: returnQuestion.placeholder }) : ""), [formatMessage, returnQuestion.placeholder]);
13
13
  const [modalVisible, setModalVisible] = useState(false);
@@ -31,7 +31,7 @@ const HostSelectReturnQuestionItem = ({ returnQuestion, children, portalHostName
31
31
  // deepestReturnQuestionWithFeedback needs to be as a dependency in order to be re-evaluated whenever it changes
32
32
  }, [handleOnModalClose, deepestReturnQuestionWithFeedback, isLeaf]);
33
33
  return (React.createElement(React.Fragment, null,
34
- React.createElement(TouchableHighlight, { style: style.container, underlayColor: containerUnderlayColor, onPress: handleOnPress },
34
+ React.createElement(TouchableHighlight, { accessibilityLabel: testID, style: style.container, testID: testID, underlayColor: containerUnderlayColor, accessible: true, onPress: handleOnPress },
35
35
  React.createElement(View, { pointerEvents: "none" },
36
36
  React.createElement(InputField, { editable: false, icon: "arrow-down", label: placeholderText, value: inputValue }))),
37
37
  React.createElement(Modal, { portalHostName: portalHostName, visible: modalVisible, header: deepestReturnQuestionWithFeedback && (React.createElement(ButtonIcon, { name: "arrow-left", testID: "modal-back-button", onPress: handleOnBackButtonPress })), scroll: true, showCloseButton: true, onClose: handleOnModalClose },
@@ -4,11 +4,11 @@ import React, { useCallback } from "react";
4
4
  import { TouchableHighlight } from "react-native";
5
5
  import { useReturnQuestionFeedbackForId } from "../../behaviors/useReturnQuestionFeedback";
6
6
  import { containerUnderlayColor, style } from "./OptionReturnQuestionItem.style";
7
- const OptionReturnQuestionItem = ({ returnQuestion, returnQuestionParentId, }) => {
7
+ const OptionReturnQuestionItem = ({ returnQuestion, returnQuestionParentId, testID, }) => {
8
8
  const { onChange } = useReturnQuestionFeedbackForId({ id: returnQuestionParentId });
9
9
  const optionText = useI18nMessage({ id: returnQuestion.name });
10
10
  const handleOnPress = useCallback(() => onChange({ returnQuestionId: returnQuestionParentId, returnQuestionFeedback: returnQuestion.id }), [onChange, returnQuestion.id, returnQuestionParentId]);
11
- return (React.createElement(TouchableHighlight, { style: style.container, underlayColor: containerUnderlayColor, onPress: handleOnPress },
11
+ return (React.createElement(TouchableHighlight, { accessibilityLabel: testID, style: style.container, testID: testID, underlayColor: containerUnderlayColor, onPress: handleOnPress },
12
12
  React.createElement(Text, { level: 3, style: style.text }, optionText)));
13
13
  };
14
14
  export { OptionReturnQuestionItem };
@@ -3,11 +3,11 @@ import React, { useCallback, useMemo } from "react";
3
3
  import { InputField } from "../../../../../../../shared/ui/components/molecules/inputField/InputField";
4
4
  import { useReturnQuestionFeedbackForId } from "../../behaviors/useReturnQuestionFeedback";
5
5
  const TEXTAREA_MIN_HEIGHT = 96;
6
- const TextareaReturnQuestionItem = ({ returnQuestion, returnQuestionParentId, }) => {
6
+ const TextareaReturnQuestionItem = ({ returnQuestion, returnQuestionParentId, testID, }) => {
7
7
  const { formatMessage } = useIntl();
8
8
  const placeholderText = useMemo(() => (returnQuestion.placeholder ? formatMessage({ id: returnQuestion.placeholder }) : ""), [formatMessage, returnQuestion.placeholder]);
9
9
  const { feedback, onChange } = useReturnQuestionFeedbackForId({ id: returnQuestionParentId });
10
10
  const handleOnChange = useCallback((value) => onChange({ returnQuestionId: returnQuestionParentId, returnQuestionFeedback: value }), [onChange, returnQuestionParentId]);
11
- return (React.createElement(InputField, { label: placeholderText, minHeight: TEXTAREA_MIN_HEIGHT, placeholder: placeholderText, value: feedback, multiline: true, onChange: handleOnChange }));
11
+ return (React.createElement(InputField, { label: placeholderText, minHeight: TEXTAREA_MIN_HEIGHT, placeholder: placeholderText, testID: testID, value: feedback, multiline: true, onChange: handleOnChange }));
12
12
  };
13
13
  export { TextareaReturnQuestionItem };
@@ -0,0 +1,13 @@
1
+ import { FC, ReactNode } from "react";
2
+ import { StyleProp, ViewStyle } from "react-native";
3
+ import { Edge } from "react-native-safe-area-context";
4
+ type SafeAreaScrollViewStyle = "safeAreaView" | "scrollView";
5
+ interface SafeAreaScrollViewProps {
6
+ readonly children: ReactNode;
7
+ readonly footer?: ReactNode;
8
+ readonly scrollerPaddingTop?: number;
9
+ readonly edges?: Edge[];
10
+ readonly style?: Partial<Record<SafeAreaScrollViewStyle, StyleProp<ViewStyle>>>;
11
+ }
12
+ declare const SafeAreaScrollView: FC<SafeAreaScrollViewProps>;
13
+ export { SafeAreaScrollView };
@@ -0,0 +1,19 @@
1
+ import React from "react";
2
+ import { ScrollView } from "react-native";
3
+ import { SafeAreaView, useSafeAreaInsets } from "react-native-safe-area-context";
4
+ import { theme } from "../../theme/theme";
5
+ import { style } from "./SafeAreaScrollView.style.ts";
6
+ const { spaceXXL } = theme();
7
+ const SafeAreaScrollView = ({ children, footer, edges = ["top", "left", "right"], style: customStyle, scrollerPaddingTop = 0, }) => {
8
+ const { bottom: safeAreaInsetBottom } = useSafeAreaInsets();
9
+ return (React.createElement(SafeAreaView, { edges: edges, style: [style.safeAreaView, customStyle?.safeAreaView] },
10
+ React.createElement(ScrollView, { contentContainerStyle: [
11
+ {
12
+ paddingTop: scrollerPaddingTop,
13
+ paddingBottom: safeAreaInsetBottom + spaceXXL,
14
+ },
15
+ customStyle?.scrollView,
16
+ ] }, children),
17
+ footer));
18
+ };
19
+ export { SafeAreaScrollView };
@@ -0,0 +1,6 @@
1
+ declare const style: {
2
+ safeAreaView: {
3
+ flex: number;
4
+ };
5
+ };
6
+ export { style };
@@ -0,0 +1,7 @@
1
+ import { StyleSheet } from "react-native";
2
+ const style = StyleSheet.create({
3
+ safeAreaView: {
4
+ flex: 1,
5
+ },
6
+ });
7
+ export { style };
@@ -0,0 +1,3 @@
1
+ import { FC } from "react";
2
+ declare const Header: FC;
3
+ export { Header };
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import { ButtonIcon } from "../../../../../../shared/ui/components/molecules/buttonIcon/ButtonIcon";
3
+ import { ButtonIconPlaceholder } from "../buttonIconPlaceholder/ButtonIconPlaceholder";
4
+ import { Logo } from "../logo/Logo";
5
+ import { style } from "./Header.style";
6
+ const Header = () => (React.createElement(React.Fragment, null,
7
+ React.createElement(Logo, { style: style.logo }),
8
+ React.createElement(ButtonIconPlaceholder, null),
9
+ React.createElement(ButtonIcon, { name: "menu", testID: "menu-button-icon", onPress: () => void 0 })));
10
+ export { Header };
@@ -0,0 +1,9 @@
1
+ declare const HEADER_HEIGHT: number;
2
+ declare const style: {
3
+ logo: {
4
+ left: number;
5
+ position: "absolute";
6
+ top: number;
7
+ };
8
+ };
9
+ export { style, HEADER_HEIGHT };
@@ -0,0 +1,12 @@
1
+ import { StyleSheet } from "react-native";
2
+ import { theme } from "../../../../theme/theme";
3
+ const { spaceXXXL } = theme();
4
+ const HEADER_HEIGHT = spaceXXXL;
5
+ const style = StyleSheet.create({
6
+ logo: {
7
+ left: 0,
8
+ position: "absolute",
9
+ top: 0,
10
+ },
11
+ });
12
+ export { style, HEADER_HEIGHT };
@@ -0,0 +1,13 @@
1
+ import { FC, ReactNode } from "react";
2
+ import { StyleProp, ViewStyle } from "react-native";
3
+ import { Edge } from "react-native-safe-area-context";
4
+ type SafeAreaScrollViewStyle = "safeAreaView" | "scrollView";
5
+ interface SafeAreaScrollViewProps {
6
+ readonly children: ReactNode;
7
+ readonly footer?: ReactNode;
8
+ readonly scrollerPaddingTop?: number;
9
+ readonly edges?: Edge[];
10
+ readonly style?: Partial<Record<SafeAreaScrollViewStyle, StyleProp<ViewStyle>>>;
11
+ }
12
+ declare const SafeAreaScrollView: FC<SafeAreaScrollViewProps>;
13
+ export { SafeAreaScrollView };
@@ -0,0 +1,19 @@
1
+ import React from "react";
2
+ import { ScrollView } from "react-native";
3
+ import { SafeAreaView, useSafeAreaInsets } from "react-native-safe-area-context";
4
+ import { theme } from "../../../theme/theme.js";
5
+ import { style } from "./SafeAreaScrollView.style.ts";
6
+ const { spaceXXL } = theme();
7
+ const SafeAreaScrollView = ({ children, footer, edges = ["top", "left", "right"], style: customStyle, scrollerPaddingTop = 0, }) => {
8
+ const { bottom: safeAreaInsetBottom } = useSafeAreaInsets();
9
+ return (React.createElement(SafeAreaView, { edges: edges, style: [style.safeAreaView, customStyle?.safeAreaView] },
10
+ React.createElement(ScrollView, { contentContainerStyle: [
11
+ {
12
+ paddingTop: scrollerPaddingTop,
13
+ paddingBottom: safeAreaInsetBottom + spaceXXL,
14
+ },
15
+ customStyle?.scrollView,
16
+ ] }, children),
17
+ footer));
18
+ };
19
+ export { SafeAreaScrollView };
@@ -0,0 +1,6 @@
1
+ declare const style: {
2
+ safeAreaView: {
3
+ flex: number;
4
+ };
5
+ };
6
+ export { style };
@@ -0,0 +1,7 @@
1
+ import { StyleSheet } from "react-native";
2
+ const style = StyleSheet.create({
3
+ safeAreaView: {
4
+ flex: 1,
5
+ },
6
+ });
7
+ export { style };
@@ -0,0 +1,2 @@
1
+ declare const usePaymentInstrumentUpdateEvents: () => void;
2
+ export { usePaymentInstrumentUpdateEvents };
@@ -0,0 +1,28 @@
1
+ import { useEvent } from "@lookiero/event";
2
+ import { useCallback, useEffect } from "react";
3
+ import { useCreateNotification } from "../../../shared/notifications";
4
+ import { MESSAGING_CONTEXT_ID } from "../../delivery/baseBootstrap";
5
+ import { I18nMessages } from "../i18n/i18n";
6
+ import { useToast } from "./useToast";
7
+ const PAYMENT_ERROR = "ERROR";
8
+ const PAYMENT_SUCCESS = "PAYMENT_INSTRUMENT_UPDATED";
9
+ const usePaymentInstrumentUpdateEvents = () => {
10
+ const { subscribe, unsubscribe } = useEvent();
11
+ const { showError, showSuccess } = useToast();
12
+ const [createNotification] = useCreateNotification({ contextId: MESSAGING_CONTEXT_ID });
13
+ const onSuccess = useCallback(({ message }) => showSuccess({ message: message.id }), [showSuccess]);
14
+ const onError = useCallback(({ error }) => {
15
+ if (error.toaster) {
16
+ showError({ message: error.toaster.id || I18nMessages.CHECKOUT_TOAST_PAYMENT_ERROR });
17
+ }
18
+ }, [showError]);
19
+ useEffect(() => {
20
+ subscribe({ event: PAYMENT_ERROR }, onError);
21
+ subscribe({ event: PAYMENT_SUCCESS }, onSuccess);
22
+ return () => {
23
+ unsubscribe({ event: PAYMENT_ERROR }, onError);
24
+ unsubscribe({ event: PAYMENT_SUCCESS }, onSuccess);
25
+ };
26
+ }, [subscribe, unsubscribe, createNotification, onError, onSuccess]);
27
+ };
28
+ export { usePaymentInstrumentUpdateEvents };
@@ -0,0 +1,11 @@
1
+ interface ShowErrorFunctionArgs {
2
+ readonly message: string;
3
+ }
4
+ interface ShowErrorFunction {
5
+ (args: ShowErrorFunctionArgs): void;
6
+ }
7
+ declare const useToast: () => {
8
+ showError: ShowErrorFunction;
9
+ showSuccess: ShowErrorFunction;
10
+ };
11
+ export { useToast };
@@ -0,0 +1,49 @@
1
+ import { Notification, useStack } from "@lookiero/aurora";
2
+ import { useIntl } from "@lookiero/i18n-react";
3
+ import { useCallback } from "react";
4
+ import { StyleSheet } from "react-native";
5
+ import { v4 as uuid } from "uuid";
6
+ import { theme } from "../theme/theme";
7
+ const { layoutXXS, elevationColor, elevationOffset, elevationOpacityM, elevationRadius } = theme();
8
+ const style = StyleSheet.create({
9
+ container: {
10
+ marginHorizontal: layoutXXS,
11
+ marginTop: layoutXXS,
12
+ shadowColor: elevationColor,
13
+ shadowOffset: elevationOffset,
14
+ shadowOpacity: elevationOpacityM,
15
+ shadowRadius: elevationRadius,
16
+ },
17
+ inAppContainer: {
18
+ top: 75,
19
+ },
20
+ });
21
+ const NOTIFICATION_DEFAULTS = {
22
+ motion: "top",
23
+ timeoutClose: 10000,
24
+ style: style.container,
25
+ };
26
+ const IN_APP_NOTIFICATION_DEFAULTS = {
27
+ ...NOTIFICATION_DEFAULTS,
28
+ style: [style.container, style.inAppContainer],
29
+ };
30
+ const iOSInAppBrowser = window.screen?.height > 667 && /FBIOS/.test(navigator.userAgent);
31
+ const getNotificationDefaults = () => (iOSInAppBrowser ? IN_APP_NOTIFICATION_DEFAULTS : NOTIFICATION_DEFAULTS);
32
+ const useToast = () => {
33
+ const Stack = useStack();
34
+ const intl = useIntl();
35
+ const translate = useCallback((message) => intl.formatMessage({ id: message, defaultMessage: message }), [intl]);
36
+ const showError = useCallback(({ message }) => Stack.alert(uuid(),
37
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
38
+ // @ts-ignore
39
+ Notification, { ...getNotificationDefaults(), text: translate(message) }), [Stack, translate]);
40
+ const showSuccess = useCallback(({ message }) => Stack.success(uuid(),
41
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
42
+ // @ts-ignore
43
+ Notification, { ...getNotificationDefaults(), text: translate(message) }), [Stack, translate]);
44
+ return {
45
+ showError,
46
+ showSuccess,
47
+ };
48
+ };
49
+ export { useToast };
@@ -0,0 +1,7 @@
1
+ import { FC } from "react";
2
+ interface CheckoutSuccessModalProps {
3
+ readonly visible: boolean;
4
+ readonly onDismiss: () => void;
5
+ }
6
+ declare const CheckoutSuccessModal: FC<CheckoutSuccessModalProps>;
7
+ export { CheckoutSuccessModal };
@@ -0,0 +1,25 @@
1
+ import { Button } from "@lookiero/aurora-next/build/components/atoms/Button/Button";
2
+ import { Text } from "@lookiero/aurora-next/build/components/primitives/Text/Text";
3
+ import { useI18nMessage } from "@lookiero/i18n-react";
4
+ import React from "react";
5
+ import { View } from "react-native";
6
+ import { Modal } from "../../../../../../shared/ui/components/layouts/modal/Modal";
7
+ import { I18nMessages } from "../../../../i18n/i18n";
8
+ import { style } from "./CheckoutSuccessModal.style";
9
+ const CheckoutSuccessModal = ({ visible, onDismiss }) => {
10
+ const titleText = useI18nMessage({ id: I18nMessages.CHECKOUT_SUCCESS_MODAL_TITLE });
11
+ const descriptionText = useI18nMessage({ id: I18nMessages.CHECKOUT_SUCCESS_MODAL_DESCRIPTION });
12
+ const buttonText = useI18nMessage({ id: I18nMessages.CHECKOUT_SUCCESS_MODAL_BUTTON });
13
+ return (React.createElement(Modal, { visible: visible, onClose: onDismiss },
14
+ React.createElement(View, { style: style.modal },
15
+ React.createElement(Text, { level: 1, style: style.modalTitle, body: true }, titleText),
16
+ React.createElement(Text, { level: 3, style: style.modalDescription, body: true }, descriptionText),
17
+ React.createElement(Button
18
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
19
+ // @ts-ignore
20
+ , {
21
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
22
+ // @ts-ignore
23
+ style: style.button, onPress: onDismiss }, buttonText))));
24
+ };
25
+ export { CheckoutSuccessModal };
@@ -0,0 +1,16 @@
1
+ declare const style: {
2
+ button: {
3
+ flex: number;
4
+ };
5
+ modal: {
6
+ padding: number;
7
+ };
8
+ modalDescription: {
9
+ marginVertical: number;
10
+ textAlign: "center";
11
+ };
12
+ modalTitle: {
13
+ textAlign: "center";
14
+ };
15
+ };
16
+ export { style };
@@ -0,0 +1,19 @@
1
+ import { StyleSheet } from "react-native";
2
+ import { theme } from "../../../../theme/theme";
3
+ const { spaceXL } = theme();
4
+ const style = StyleSheet.create({
5
+ button: {
6
+ flex: 0,
7
+ },
8
+ modal: {
9
+ padding: spaceXL,
10
+ },
11
+ modalDescription: {
12
+ marginVertical: spaceXL,
13
+ textAlign: "center",
14
+ },
15
+ modalTitle: {
16
+ textAlign: "center",
17
+ },
18
+ });
19
+ export { style };
@@ -32,6 +32,6 @@ const CheckoutQuestionsForm = ({ checkoutQuestions, submitButtonDisabled, onSubm
32
32
  return (React.createElement(React.Fragment, null,
33
33
  React.createElement(CheckoutQuestionItemProvider, { checkoutQuestionItems: checkoutQuestionItems },
34
34
  React.createElement(CheckoutQuestions, { checkoutQuestions: filteredCheckoutQuestions })),
35
- React.createElement(Button, { busy: submitButtonDisabled, style: style.button, onPress: handlePress }, buttonText)));
35
+ React.createElement(Button, { busy: submitButtonDisabled, style: style.button, testID: "checkout-feedback-button", onPress: handlePress }, buttonText)));
36
36
  };
37
37
  export { CheckoutQuestionsForm };
@@ -0,0 +1,6 @@
1
+ import { FC } from "react";
2
+ type IntroProps = {
3
+ readonly customerId: string;
4
+ };
5
+ declare const Intro: FC<IntroProps>;
6
+ export { Intro };
@@ -0,0 +1,52 @@
1
+ import { Button } from "@lookiero/aurora-next/build/components/atoms/Button/Button";
2
+ import { Icon } from "@lookiero/aurora-next/build/components/primitives/Icon/Icon";
3
+ import { Text } from "@lookiero/aurora-next/build/components/primitives/Text/Text";
4
+ import { useI18nMessage } from "@lookiero/i18n-react";
5
+ import { CommandStatus, QueryStatus } from "@lookiero/messaging-react";
6
+ import React from "react";
7
+ import { Platform, View } from "react-native";
8
+ import { Spinner } from "../../../../shared/ui/components/atoms/spinner/Spinner";
9
+ import { useIncrementIntroShownCount } from "../../../domain/uiSetting/react/useIncrementIntroShownCount";
10
+ import { useViewFiveItemsDiscountByCustomerId } from "../../../projection/checkout/react/useViewFiveItemsDiscountByCustomerId";
11
+ import { Body } from "../../components/layouts/body/Body";
12
+ import { SafeAreaScrollView } from "../../components/templates/SafeAreaScrollView";
13
+ import { I18nMessages } from "../../i18n/i18n";
14
+ import { HEADER_HEIGHT } from "../navigation/components/header/Header.style";
15
+ import { style } from "./Intro.style";
16
+ const Bullet = ({ text }) => (React.createElement(View, { style: style.bullet },
17
+ React.createElement(Icon, { name: "rounded-tick", style: style.tickIcon }),
18
+ React.createElement(Text, { level: 2, detail: true }, text)));
19
+ const Intro = ({ customerId }) => {
20
+ const titleText = useI18nMessage({ id: I18nMessages.INTRO_TITLE });
21
+ const subTitleText = useI18nMessage({ id: I18nMessages.INTRO_SUBTITLE });
22
+ const discountText = useI18nMessage({ id: I18nMessages.INTRO_DISCOUNT });
23
+ const bulletOneText = useI18nMessage({ id: I18nMessages.INTRO_BULLET_ONE });
24
+ const bulletTwoText = useI18nMessage({ id: I18nMessages.INTRO_BULLET_TWO });
25
+ const bulletThreeText = useI18nMessage({ id: I18nMessages.INTRO_BULLET_THREE });
26
+ const buttonText = useI18nMessage({ id: I18nMessages.INTRO_BUTTON });
27
+ const [fiveItemsDiscount, fiveItemsDiscountStatus] = useViewFiveItemsDiscountByCustomerId({
28
+ customerId,
29
+ });
30
+ const [incrementIntroShownCount, incrementIntroShownCountStatus] = useIncrementIntroShownCount();
31
+ if (fiveItemsDiscountStatus === QueryStatus.LOADING)
32
+ return React.createElement(Spinner, null);
33
+ return (React.createElement(SafeAreaScrollView, { scrollerPaddingTop: Platform.OS === "web" || Platform.OS === "android" ? HEADER_HEIGHT : 0 },
34
+ React.createElement(Body, { style: { column: style.bodyColumn } },
35
+ React.createElement(View, { style: style.intro },
36
+ React.createElement(View, { style: style.content },
37
+ React.createElement(Text, { level: 3, style: style.title, heading: true }, titleText),
38
+ React.createElement(Text, { level: 3, style: style.subtitle, body: true }, subTitleText),
39
+ fiveItemsDiscount !== 0 && (React.createElement(View, { style: style.discountContainer },
40
+ React.createElement(View, { style: style.discount },
41
+ React.createElement(Text, { level: 2, heading: true },
42
+ "- ",
43
+ fiveItemsDiscount),
44
+ React.createElement(Text, { level: 3, style: style.percentage, heading: true }, "%")),
45
+ React.createElement(Text, { level: 3, body: true }, discountText))),
46
+ React.createElement(View, { style: style.description },
47
+ React.createElement(Bullet, { text: bulletOneText }),
48
+ React.createElement(Bullet, { text: bulletTwoText }),
49
+ React.createElement(Bullet, { text: bulletThreeText }))),
50
+ React.createElement(Button, { disabled: incrementIntroShownCountStatus === CommandStatus.LOADING, onPress: incrementIntroShownCount }, buttonText)))));
51
+ };
52
+ export { Intro };