@lookiero/checkout 1.3.0 → 2.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 (55) hide show
  1. package/README.md +1 -1
  2. package/dist/domain/checkoutBooking/event/createNotificationWhenCheckoutBookingExpired.d.ts +6 -0
  3. package/dist/domain/checkoutBooking/event/createNotificationWhenCheckoutBookingExpired.js +13 -0
  4. package/dist/infrastructure/domain/checkout/react/useStartCheckout.js +1 -1
  5. package/dist/infrastructure/domain/uiSetting/react/useIncrementIntroShownCount.d.ts +10 -0
  6. package/dist/infrastructure/domain/uiSetting/react/useIncrementIntroShownCount.js +11 -0
  7. package/dist/infrastructure/projection/uiSetting/react/useShouldIntroBeShown.d.ts +6 -0
  8. package/dist/infrastructure/projection/uiSetting/react/useShouldIntroBeShown.js +7 -0
  9. package/dist/infrastructure/projection/uiSetting/react/useViewIntroShownCount.d.ts +6 -0
  10. package/dist/infrastructure/projection/uiSetting/react/useViewIntroShownCount.js +9 -0
  11. package/dist/infrastructure/ui/Root.d.ts +1 -3
  12. package/dist/infrastructure/ui/Root.js +2 -2
  13. package/dist/infrastructure/ui/hooks/usePaymentInstrumentUpdateEvents.d.ts +2 -0
  14. package/dist/infrastructure/ui/hooks/usePaymentInstrumentUpdateEvents.js +28 -0
  15. package/dist/infrastructure/ui/routing/Routing.d.ts +1 -3
  16. package/dist/infrastructure/ui/routing/Routing.js +2 -2
  17. package/dist/infrastructure/ui/views/App.d.ts +2 -4
  18. package/dist/infrastructure/ui/views/App.js +2 -2
  19. package/dist/infrastructure/ui/views/checkout/components/checkoutSuccessModal/CheckoutSuccessModal.d.ts +7 -0
  20. package/dist/infrastructure/ui/views/checkout/components/checkoutSuccessModal/CheckoutSuccessModal.js +25 -0
  21. package/dist/infrastructure/ui/views/checkout/components/checkoutSuccessModal/CheckoutSuccessModal.style.d.ts +16 -0
  22. package/dist/infrastructure/ui/views/checkout/components/checkoutSuccessModal/CheckoutSuccessModal.style.js +19 -0
  23. package/dist/infrastructure/ui/views/intro/Intro.d.ts +6 -0
  24. package/dist/infrastructure/ui/views/intro/Intro.js +52 -0
  25. package/dist/infrastructure/ui/views/intro/Intro.style.d.ts +52 -0
  26. package/dist/infrastructure/ui/views/intro/Intro.style.js +55 -0
  27. package/dist/infrastructure/ui/views/item/Item.style.d.ts +15 -0
  28. package/dist/infrastructure/ui/views/item/Item.style.js +18 -0
  29. package/dist/infrastructure/ui/views/item/components/productVariant/ProductVariant.d.ts +26 -0
  30. package/dist/infrastructure/ui/views/item/components/productVariant/ProductVariant.js +44 -0
  31. package/dist/infrastructure/ui/views/item/components/productVariant/ProductVariant.style.d.ts +45 -0
  32. package/dist/infrastructure/ui/views/item/components/productVariant/ProductVariant.style.js +53 -0
  33. package/dist/infrastructure/ui/views/item/components/sizeChangeModal/SizeChangeModal.d.ts +7 -0
  34. package/dist/infrastructure/ui/views/item/components/sizeChangeModal/SizeChangeModal.js +25 -0
  35. package/dist/infrastructure/ui/views/item/components/sizeChangeModal/SizeChangeModal.style.d.ts +16 -0
  36. package/dist/infrastructure/ui/views/item/components/sizeChangeModal/SizeChangeModal.style.js +19 -0
  37. package/dist/infrastructure/ui/views/navigation/Navigation.d.ts +2 -3
  38. package/dist/infrastructure/ui/views/navigation/Navigation.js +6 -20
  39. package/dist/infrastructure/ui/views/navigation/components/header/Header.d.ts +0 -12
  40. package/dist/infrastructure/ui/views/navigation/components/header/Header.js +2 -5
  41. package/dist/shared/notifications/domain/notification/command/createNotification.d.ts +17 -0
  42. package/dist/shared/notifications/domain/notification/command/createNotification.js +7 -0
  43. package/dist/shared/notifications/infrastructure/domain/notification/react/useCreateNotification.d.ts +21 -0
  44. package/dist/shared/notifications/infrastructure/domain/notification/react/useCreateNotification.js +22 -0
  45. package/dist/shared/notifications/infrastructure/ui/components/NotificationItem.d.ts +12 -0
  46. package/dist/shared/notifications/infrastructure/ui/components/NotificationItem.js +24 -0
  47. package/dist/shared/notifications/infrastructure/ui/components/Notifications.d.ts +9 -0
  48. package/dist/shared/notifications/infrastructure/ui/components/Notifications.js +20 -0
  49. package/dist/shared/notifications/infrastructure/ui/components/Notifications.style.d.ts +36 -0
  50. package/dist/shared/notifications/infrastructure/ui/components/Notifications.style.js +31 -0
  51. package/dist/shared/tracking/infrastructure/usePageView.d.ts +13 -0
  52. package/dist/shared/tracking/infrastructure/usePageView.js +27 -0
  53. package/dist/shared/ui/components/atoms/error/Error.style.d.ts +6 -0
  54. package/dist/shared/ui/components/atoms/error/Error.style.js +9 -0
  55. package/package.json +27 -24
package/README.md CHANGED
@@ -38,7 +38,7 @@ Once we can replace the build of Jenkins for NPM one, we are going to be able to
38
38
  "dependencies": {
39
39
  (...)
40
40
  "@expo/dev-server": "0.1.120",
41
- "expo-modules-core": "^1.2.6",
41
+ "expo-modules-core": "^1.0.3",
42
42
  "inline-style-prefixer": "6.0.1",
43
43
  (...)
44
44
  },
@@ -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 };
@@ -8,7 +8,7 @@ const useStartCheckout = ({ checkoutId, logger }) => {
8
8
  const start = useCallback(async () => {
9
9
  invariant(checkoutId, "CheckoutId must be defined in order to start checkout");
10
10
  try {
11
- await commandBus(startCheckout({ aggregateId: checkoutId }));
11
+ return await commandBus(startCheckout({ aggregateId: checkoutId }));
12
12
  }
13
13
  catch (error) {
14
14
  if (!error?.message?.includes("Checkout is already started")) {
@@ -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 };
@@ -4,7 +4,6 @@ import { ComponentType } from "react";
4
4
  import { useRoutes as reactRouterUseRoutes } from "react-router-native";
5
5
  import { Customer } from "../../projection/shared/customer";
6
6
  import { SentryEnvironment } from "../../shared/logging/SentryLogger";
7
- import { Menu, TabBar } from "./views/navigation/Navigation";
8
7
  interface RootFunctionArgs {
9
8
  readonly Messaging: MessagingRoot;
10
9
  readonly I18n: I18n;
@@ -19,9 +18,8 @@ interface RootProps {
19
18
  readonly basePath: string;
20
19
  readonly locale?: string;
21
20
  readonly customer: Customer | undefined;
22
- readonly menu: Menu;
23
- readonly tabBar: TabBar;
24
21
  readonly onNotAccessible: () => void;
22
+ readonly onOpenMenu: () => void;
25
23
  readonly useRedirect: () => Record<string, string>;
26
24
  readonly useRoutes?: typeof reactRouterUseRoutes;
27
25
  }
@@ -6,10 +6,10 @@ import { sentryLoggerHOC } from "../../shared/logging/SentryLoggerHOC";
6
6
  import { Routing } from "./routing/Routing";
7
7
  const root = ({ Messaging, I18n, getAuthToken, development, sentry }) => {
8
8
  // eslint-disable-next-line react/display-name, react/prop-types
9
- const Root = ({ basePath, locale = "en", customer, menu, tabBar, onNotAccessible, useRedirect, useRoutes = reactRouterUseRoutes, }) => {
9
+ const Root = ({ basePath, locale = "en", customer, onNotAccessible, onOpenMenu, useRedirect, useRoutes = reactRouterUseRoutes, }) => {
10
10
  const handleOnI18nError = useCallback(() => void 0, []);
11
11
  return (React.createElement(Messaging, { includeReactQueryDevTools: Platform.OS === "web" },
12
- React.createElement(Routing, { I18n: I18n, basePath: basePath, customer: customer, getAuthToken: getAuthToken, locale: locale, menu: menu, tabBar: tabBar, useRedirect: useRedirect, useRoutes: useRoutes, onI18nError: development ? undefined : handleOnI18nError, onNotAccessible: onNotAccessible })));
12
+ React.createElement(Routing, { I18n: I18n, basePath: basePath, customer: customer, getAuthToken: getAuthToken, locale: locale, useRedirect: useRedirect, useRoutes: useRoutes, onI18nError: development ? undefined : handleOnI18nError, onNotAccessible: onNotAccessible, onOpenMenu: onOpenMenu })));
13
13
  };
14
14
  return sentryLoggerHOC({ logger: sentryLogger(sentry) })(Root);
15
15
  };
@@ -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 };
@@ -2,16 +2,14 @@ import { I18n } from "@lookiero/i18n-react";
2
2
  import React from "react";
3
3
  import { useRoutes as reactRouterUseRoutes } from "react-router-native";
4
4
  import { Customer } from "../../../projection/shared/customer";
5
- import { Menu, TabBar } from "../views/navigation/Navigation";
6
5
  interface RoutingProps {
7
6
  readonly basePath?: string;
8
7
  readonly customer: Customer | undefined;
9
8
  readonly locale: string;
10
9
  readonly I18n: I18n;
11
- readonly menu: Menu;
12
- readonly tabBar: TabBar;
13
10
  readonly getAuthToken: () => Promise<string>;
14
11
  readonly onNotAccessible: () => void;
12
+ readonly onOpenMenu: () => void;
15
13
  readonly onI18nError?: (err: Error) => void;
16
14
  readonly useRedirect: () => Record<string, string>;
17
15
  readonly useRoutes: typeof reactRouterUseRoutes;
@@ -11,7 +11,7 @@ const Item = lazy(() => import("../views/item/Item").then((module) => ({ default
11
11
  const Summary = lazy(() => import("../views/summary/Summary").then((module) => ({ default: module.Summary })));
12
12
  const Checkout = lazy(() => import("../views/checkout/Checkout").then((module) => ({ default: module.Checkout })));
13
13
  const Feedback = lazy(() => import("../views/feedback/Feedback").then((module) => ({ default: module.Feedback })));
14
- const Routing = ({ basePath = "", customer, locale, I18n, menu, tabBar, getAuthToken, onI18nError, onNotAccessible, useRedirect, useRoutes = reactRouterUseRoutes, }) => {
14
+ const Routing = ({ basePath = "", customer, locale, I18n, getAuthToken, onI18nError, onNotAccessible, onOpenMenu, useRedirect, useRoutes = reactRouterUseRoutes, }) => {
15
15
  return useRoutes([
16
16
  {
17
17
  path: "",
@@ -19,7 +19,7 @@ const Routing = ({ basePath = "", customer, locale, I18n, menu, tabBar, getAuthT
19
19
  React.createElement(CheckoutAccessibilityMiddleware, { customerId: customer?.customerId, onNotAccessible: onNotAccessible },
20
20
  React.createElement(I18n, { loader: React.createElement(Spinner, null), locale: locale, onError: onI18nError },
21
21
  React.createElement(CheckoutMiddleware, { customerId: customer?.customerId },
22
- React.createElement(App, { country: customer?.country, customerId: customer?.customerId, menu: menu, tabBar: tabBar },
22
+ React.createElement(App, { country: customer?.country, customerId: customer?.customerId, onOpenMenu: onOpenMenu },
23
23
  React.createElement(Outlet, null))))))),
24
24
  children: [
25
25
  {
@@ -1,12 +1,10 @@
1
1
  import { FC } from "react";
2
2
  import { Country } from "../../../projection/shared/country";
3
- import { Menu, TabBar } from "./navigation/Navigation";
4
3
  interface AppProps {
4
+ readonly children: JSX.Element;
5
5
  readonly customerId: string;
6
6
  readonly country: Country;
7
- readonly menu: Menu;
8
- readonly tabBar: TabBar;
9
- readonly children: JSX.Element;
7
+ readonly onOpenMenu: () => void;
10
8
  }
11
9
  declare const App: FC<AppProps>;
12
10
  export { App };
@@ -7,9 +7,9 @@ import { MESSAGING_CONTEXT_ID } from "../../delivery/baseBootstrap";
7
7
  import { theme } from "../theme/theme";
8
8
  import { Navigation } from "./navigation/Navigation";
9
9
  const { colorBase } = theme();
10
- const App = ({ customerId, country, menu, tabBar, children }) => (React.createElement(SafeAreaProvider, null,
10
+ const App = ({ children, customerId, country, onOpenMenu }) => (React.createElement(SafeAreaProvider, null,
11
11
  React.createElement(PortalProvider, null,
12
12
  React.createElement(StatusBar, { backgroundColor: colorBase, barStyle: "dark-content", translucent: true }),
13
13
  React.createElement(Notifications, { contextId: MESSAGING_CONTEXT_ID }),
14
- React.createElement(Navigation, { country: country, customerId: customerId, menu: menu, tabBar: tabBar }, children))));
14
+ React.createElement(Navigation, { country: country, customerId: customerId, onOpenMenu: onOpenMenu }, children))));
15
15
  export { App };
@@ -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 };
@@ -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 };
@@ -0,0 +1,52 @@
1
+ declare const style: {
2
+ bodyColumn: {
3
+ paddingHorizontal: number;
4
+ };
5
+ bullet: {
6
+ alignItems: "center";
7
+ flexDirection: "row";
8
+ marginVertical: number;
9
+ };
10
+ content: {
11
+ alignItems: "center";
12
+ };
13
+ description: {
14
+ borderWidth: number;
15
+ marginBottom: number;
16
+ padding: number;
17
+ width: string;
18
+ };
19
+ discount: {
20
+ alignItems: "flex-end";
21
+ flexDirection: "row";
22
+ justifyContent: "center";
23
+ marginBottom: number;
24
+ };
25
+ discountContainer: {
26
+ alignItems: "center";
27
+ backgroundColor: string;
28
+ marginBottom: number;
29
+ padding: number;
30
+ textAlign: "center";
31
+ width: string;
32
+ };
33
+ intro: {
34
+ flex: number;
35
+ justifyContent: "space-between";
36
+ };
37
+ percentage: {
38
+ marginLeft: number;
39
+ };
40
+ subtitle: {
41
+ marginBottom: number;
42
+ textAlign: "center";
43
+ };
44
+ tickIcon: {
45
+ marginRight: number;
46
+ };
47
+ title: {
48
+ marginBottom: number;
49
+ textAlign: "center";
50
+ };
51
+ };
52
+ export { style };
@@ -0,0 +1,55 @@
1
+ import { StyleSheet } from "react-native";
2
+ import { theme } from "../../theme/theme";
3
+ const { borderSize, colorAccent, spaceXS, spaceS, spaceM, spaceL, spaceXL } = theme();
4
+ const style = StyleSheet.create({
5
+ bodyColumn: {
6
+ paddingHorizontal: spaceXL,
7
+ },
8
+ bullet: {
9
+ alignItems: "center",
10
+ flexDirection: "row",
11
+ marginVertical: spaceS,
12
+ },
13
+ content: {
14
+ alignItems: "center",
15
+ },
16
+ description: {
17
+ borderWidth: borderSize,
18
+ marginBottom: spaceXL,
19
+ padding: spaceM,
20
+ width: "100%",
21
+ },
22
+ discount: {
23
+ alignItems: "flex-end",
24
+ flexDirection: "row",
25
+ justifyContent: "center",
26
+ marginBottom: spaceS,
27
+ },
28
+ discountContainer: {
29
+ alignItems: "center",
30
+ backgroundColor: colorAccent,
31
+ marginBottom: spaceL,
32
+ padding: spaceM,
33
+ textAlign: "center",
34
+ width: "100%",
35
+ },
36
+ intro: {
37
+ flex: 1,
38
+ justifyContent: "space-between",
39
+ },
40
+ percentage: {
41
+ marginLeft: spaceXS,
42
+ },
43
+ subtitle: {
44
+ marginBottom: spaceXL,
45
+ textAlign: "center",
46
+ },
47
+ tickIcon: {
48
+ marginRight: spaceS,
49
+ },
50
+ title: {
51
+ marginBottom: spaceM,
52
+ textAlign: "center",
53
+ },
54
+ });
55
+ export { style };
@@ -0,0 +1,15 @@
1
+ declare const style: {
2
+ content: {
3
+ paddingHorizontal: number;
4
+ };
5
+ feedbackContainer: {
6
+ borderTopColor: string;
7
+ borderTopWidth: number;
8
+ marginVertical: number;
9
+ };
10
+ sliderContainer: {
11
+ marginBottom: number;
12
+ minHeight: number;
13
+ };
14
+ };
15
+ export { style };
@@ -0,0 +1,18 @@
1
+ import { StyleSheet } from "react-native";
2
+ import { theme } from "../../theme/theme";
3
+ const { borderSize, colorGrayscaleM, spaceXL } = theme();
4
+ const style = StyleSheet.create({
5
+ content: {
6
+ paddingHorizontal: spaceXL,
7
+ },
8
+ feedbackContainer: {
9
+ borderTopColor: colorGrayscaleM,
10
+ borderTopWidth: borderSize,
11
+ marginVertical: spaceXL,
12
+ },
13
+ sliderContainer: {
14
+ marginBottom: spaceXL,
15
+ minHeight: 500,
16
+ },
17
+ });
18
+ export { style };
@@ -0,0 +1,26 @@
1
+ import { FC } from "react";
2
+ import { ImageStyle, StyleProp } from "react-native";
3
+ import { CheckoutItemStatus } from "../../../../../../domain/checkoutItem/model/checkoutItem";
4
+ import { ColorProjection, MediaProjection } from "../../../../../../projection/checkoutItem/checkoutItem";
5
+ import { Country } from "../../../../../../projection/shared/country";
6
+ import { PriceProjection } from "../../../../../../projection/shared/price";
7
+ import { SizeProjection } from "../../../../../../projection/shared/size";
8
+ interface ProductVariantStyle {
9
+ readonly image: StyleProp<ImageStyle>;
10
+ }
11
+ interface ProductVariantProps {
12
+ readonly media: MediaProjection[];
13
+ readonly brand: string;
14
+ readonly name: string;
15
+ readonly price: PriceProjection;
16
+ readonly size: SizeProjection;
17
+ readonly color: ColorProjection;
18
+ readonly status?: CheckoutItemStatus;
19
+ readonly discarded?: boolean;
20
+ readonly country: Country;
21
+ readonly style?: Partial<ProductVariantStyle>;
22
+ readonly onPress?: () => void;
23
+ }
24
+ declare const ProductVariant: FC<ProductVariantProps>;
25
+ export type { ProductVariantStyle };
26
+ export { ProductVariant };
@@ -0,0 +1,44 @@
1
+ import { Text } from "@lookiero/aurora-next/build/components/primitives/Text/Text";
2
+ import { useI18nMessage } from "@lookiero/i18n-react";
3
+ import React from "react";
4
+ import { Image, Pressable, View } from "react-native";
5
+ import Svg, { Line } from "react-native-svg";
6
+ import { CheckoutItemStatus } from "../../../../../../domain/checkoutItem/model/checkoutItem";
7
+ import { size } from "../../../../../../projection/shared/size";
8
+ import { Icon } from "../../../../../../shared/ui/components/atoms/icon/Icon";
9
+ import { Price } from "../../../../components/atoms/price/Price";
10
+ import { useMediaImage } from "../../../../hooks/useMediaImage";
11
+ import { COLOR_I18N_PREFIX, I18nMessages } from "../../../../i18n/i18n";
12
+ import { theme } from "../../../../theme/theme";
13
+ import { IMAGE_WIDTH, style } from "./ProductVariant.style";
14
+ const { colorContent } = theme();
15
+ const ProductVariant = ({ media, brand, name, price, size: sizeProjection, color, status, discarded, country, style: customStyle, onPress, }) => {
16
+ const uniqueText = useI18nMessage({ id: I18nMessages.ITEM_UNIQUE });
17
+ const colorLabel = useI18nMessage({ id: color.label, prefix: COLOR_I18N_PREFIX });
18
+ const sizeChangeText = useI18nMessage({ id: I18nMessages.PRODUCT_VARIANT_SIZE_CHANGE });
19
+ const cdnImageUrl = useMediaImage();
20
+ return (React.createElement(Pressable, { pointerEvents: onPress ? "auto" : "none", style: style.container, testID: "product-variant", onPress: onPress },
21
+ React.createElement(View, { style: style.row },
22
+ React.createElement(View, null,
23
+ React.createElement(Image, { resizeMode: "contain", style: [style.media, customStyle?.image], testID: "product-variant-media", source: {
24
+ uri: cdnImageUrl({
25
+ url: media[0]?.url,
26
+ width: IMAGE_WIDTH,
27
+ }),
28
+ } }),
29
+ discarded && (React.createElement(Svg, { preserveAspectRatio: "none", stroke: colorContent, style: style.discarded, testID: "discarded", viewBox: "0 0 100 100" },
30
+ React.createElement(Line, { vectorEffect: "non-scaling-stroke", x1: "100", x2: "0", y1: "0", y2: "100" })))),
31
+ React.createElement(View, { style: style.descriptionContainer },
32
+ React.createElement(View, null,
33
+ React.createElement(Text, { level: 2, style: style.brand, detail: true }, brand),
34
+ React.createElement(Text, { level: 2, detail: true }, name),
35
+ React.createElement(Text, { level: 2, style: style.priceAndColor, detail: true },
36
+ sizeProjection.unique ? uniqueText : size({ size: sizeProjection, country }),
37
+ " / ",
38
+ colorLabel),
39
+ status === CheckoutItemStatus.REPLACED && (React.createElement(View, { style: style.sizeChange },
40
+ React.createElement(Text, { level: 3, style: style.sizeChangeText, detail: true }, sizeChangeText)))),
41
+ React.createElement(Price, { price: price, variant: "detail" }))),
42
+ onPress && React.createElement(Icon, { name: "arrow-right" })));
43
+ };
44
+ export { ProductVariant };
@@ -0,0 +1,45 @@
1
+ declare const IMAGE_WIDTH = 96;
2
+ declare const style: {
3
+ brand: {
4
+ color: string;
5
+ };
6
+ container: {
7
+ flexDirection: "row";
8
+ justifyContent: "space-between";
9
+ };
10
+ descriptionContainer: {
11
+ justifyContent: "space-between";
12
+ marginLeft: number;
13
+ };
14
+ discarded: {
15
+ height: string;
16
+ left: number;
17
+ position: "absolute";
18
+ top: number;
19
+ width: string;
20
+ zIndex: number;
21
+ };
22
+ media: {
23
+ borderColor: string;
24
+ borderWidth: number;
25
+ height: number;
26
+ width: number;
27
+ };
28
+ priceAndColor: {
29
+ color: string;
30
+ };
31
+ row: {
32
+ flexDirection: "row";
33
+ };
34
+ sizeChange: {
35
+ width?: string | undefined;
36
+ backgroundColor: string;
37
+ marginTop: number;
38
+ paddingHorizontal: number;
39
+ paddingVertical: number;
40
+ };
41
+ sizeChangeText: {
42
+ textTransform: "uppercase";
43
+ };
44
+ };
45
+ export { style, IMAGE_WIDTH };