@lookiero/checkout 0.6.4 → 0.7.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 (48) hide show
  1. package/dist/index.d.ts +4 -2
  2. package/dist/index.js +2 -2
  3. package/dist/infrastructure/ui/Root.d.ts +6 -2
  4. package/dist/infrastructure/ui/Root.js +10 -6
  5. package/dist/infrastructure/ui/i18n/i18n.d.ts +0 -7
  6. package/dist/infrastructure/ui/i18n/i18n.js +0 -7
  7. package/dist/infrastructure/ui/routing/CheckoutAccessibilityMiddleware.js +1 -1
  8. package/dist/infrastructure/ui/routing/CheckoutMiddleware.js +13 -29
  9. package/dist/infrastructure/ui/routing/Routing.d.ts +11 -3
  10. package/dist/infrastructure/ui/routing/Routing.js +12 -12
  11. package/dist/infrastructure/ui/routing/routes.d.ts +0 -1
  12. package/dist/infrastructure/ui/routing/routes.js +0 -1
  13. package/dist/infrastructure/ui/settings/UISettings.d.ts +0 -1
  14. package/dist/infrastructure/ui/settings/UISettings.js +0 -1
  15. package/dist/shared/logging/SentryDependencies.d.ts +11 -0
  16. package/dist/shared/logging/SentryDependencies.js +17 -0
  17. package/dist/shared/logging/SentryDependencies.native.d.ts +10 -0
  18. package/dist/shared/logging/SentryDependencies.native.js +15 -0
  19. package/dist/shared/logging/SentryLogger.d.ts +19 -0
  20. package/dist/shared/logging/SentryLogger.js +122 -0
  21. package/dist/shared/logging/reactRouterV6Instrumentation/NativeReactRouterV6Instrumentation.d.ts +49 -0
  22. package/dist/shared/logging/reactRouterV6Instrumentation/NativeReactRouterV6Instrumentation.js +131 -0
  23. package/dist/shared/logging/reactRouterV6Instrumentation/location.d.ts +3 -0
  24. package/dist/shared/logging/reactRouterV6Instrumentation/location.js +5 -0
  25. package/dist/shared/logging/reactRouterV6Instrumentation/normalizedNameAndMatchForLocation.d.ts +12 -0
  26. package/dist/shared/logging/reactRouterV6Instrumentation/normalizedNameAndMatchForLocation.js +34 -0
  27. package/dist/shared/logging/reactRouterV6Instrumentation/reactRouterV6Instrumentation.d.ts +15 -0
  28. package/dist/shared/logging/reactRouterV6Instrumentation/reactRouterV6Instrumentation.js +92 -0
  29. package/dist/shared/logging/reactRouterV6Instrumentation/types.d.ts +9 -0
  30. package/dist/shared/logging/reactRouterV6Instrumentation/types.js +1 -0
  31. package/dist/shared/logging/types.d.ts +22 -0
  32. package/dist/shared/logging/types.js +1 -0
  33. package/dist/shared/ui/components/atoms/field/Field.js +5 -13
  34. package/dist/shared/ui/components/atoms/field/Field.style.js +2 -2
  35. package/dist/shared/ui/components/molecules/inputField/InputField.js +2 -2
  36. package/dist/shared/ui/components/molecules/inputField/InputField.style.d.ts +1 -0
  37. package/dist/shared/ui/components/molecules/inputField/InputField.style.js +1 -0
  38. package/package.json +2 -1
  39. package/dist/infrastructure/domain/uiSetting/react/useIncrementIntroShownCount.d.ts +0 -10
  40. package/dist/infrastructure/domain/uiSetting/react/useIncrementIntroShownCount.js +0 -11
  41. package/dist/infrastructure/projection/uiSetting/react/useShouldIntroBeShown.d.ts +0 -6
  42. package/dist/infrastructure/projection/uiSetting/react/useShouldIntroBeShown.js +0 -7
  43. package/dist/infrastructure/projection/uiSetting/react/useViewIntroShownCount.d.ts +0 -6
  44. package/dist/infrastructure/projection/uiSetting/react/useViewIntroShownCount.js +0 -9
  45. package/dist/infrastructure/ui/views/intro/Intro.d.ts +0 -6
  46. package/dist/infrastructure/ui/views/intro/Intro.js +0 -52
  47. package/dist/infrastructure/ui/views/intro/Intro.style.d.ts +0 -52
  48. package/dist/infrastructure/ui/views/intro/Intro.style.js +0 -55
@@ -0,0 +1,131 @@
1
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
2
+ import { RoutingInstrumentation } from "@sentry/react-native";
3
+ import { logger } from "@sentry/utils";
4
+ import React from "react";
5
+ import { stripFirstSlugFromLocation } from "./location";
6
+ import { normalizedNameAndMatchForLocation } from "./normalizedNameAndMatchForLocation";
7
+ const transactionContext = ({ instrumentationName, route, previousRoute = null, }) => ({
8
+ name: route.name,
9
+ op: "navigation",
10
+ tags: {
11
+ ["routing.instrumentation"]: instrumentationName,
12
+ ["routing.route.name"]: route.name,
13
+ },
14
+ data: {
15
+ route,
16
+ previousRoute,
17
+ },
18
+ });
19
+ class NativeReactRouterV6Instrumentation extends RoutingInstrumentation {
20
+ static instrumentationName = "react-router-v6";
21
+ useEffect;
22
+ useLocation;
23
+ matchRoutes;
24
+ transformLocation;
25
+ prevRoute;
26
+ recentRouteKeys = [];
27
+ latestTransaction;
28
+ maxRecentRouteLen = 200;
29
+ constructor({ useEffect, useLocation, matchRoutes, transformLocation = stripFirstSlugFromLocation, }) {
30
+ super();
31
+ this.useEffect = useEffect;
32
+ this.useLocation = useLocation;
33
+ this.matchRoutes = matchRoutes;
34
+ this.transformLocation = transformLocation;
35
+ }
36
+ registerRoutingInstrumentation(listener, beforeNavigate, onConfirmRoute) {
37
+ super.registerRoutingInstrumentation(listener, beforeNavigate, onConfirmRoute);
38
+ this.latestTransaction = this.onRouteWillChange(INITIAL_TRANSACTION_CONTEXT);
39
+ }
40
+ onRouteChange(location, routes, updateLatestTransaction = false) {
41
+ const currentRoute = this.currentRouteFromLocation(location, routes);
42
+ if (!currentRoute || (this.prevRoute && currentRoute.key === this.prevRoute.key)) {
43
+ return;
44
+ }
45
+ const originalContext = transactionContext({
46
+ instrumentationName: NativeReactRouterV6Instrumentation.instrumentationName,
47
+ route: currentRoute,
48
+ previousRoute: this.prevRoute,
49
+ });
50
+ let finalContext = this._beforeNavigate?.(originalContext);
51
+ if (!finalContext) {
52
+ logger.error(`[ReactRouterV6Instrumentation] beforeNavigate returned ${finalContext}, return context.sampled = false to not send transaction.`);
53
+ finalContext = { ...originalContext, sampled: false };
54
+ }
55
+ if (finalContext.sampled === false) {
56
+ this.onBeforeNavigateNotSampled(finalContext.name);
57
+ }
58
+ if (updateLatestTransaction && this.latestTransaction) {
59
+ this.latestTransaction.updateWithContext(finalContext);
60
+ }
61
+ else {
62
+ this.latestTransaction = this.onRouteWillChange(finalContext);
63
+ }
64
+ this.pushRecentRouteKey(currentRoute.key);
65
+ this.prevRoute = currentRoute;
66
+ }
67
+ currentRouteFromLocation(location, routes) {
68
+ const normalizedLocation = this.transformLocation(location);
69
+ const branches = this.matchRoutes(routes, normalizedLocation);
70
+ if (!branches) {
71
+ return null;
72
+ }
73
+ const [normalizedName, match] = normalizedNameAndMatchForLocation({
74
+ location: normalizedLocation,
75
+ routes,
76
+ branches,
77
+ });
78
+ return {
79
+ name: normalizedName,
80
+ key: normalizedName,
81
+ params: match?.params ?? {},
82
+ hasBeenSeen: this.recentRouteKeys.includes(normalizedName),
83
+ };
84
+ }
85
+ pushRecentRouteKey(key) {
86
+ this.recentRouteKeys.push(key);
87
+ if (this.recentRouteKeys.length > this.maxRecentRouteLen) {
88
+ this.recentRouteKeys = this.recentRouteKeys.slice(this.recentRouteKeys.length - this.maxRecentRouteLen);
89
+ }
90
+ }
91
+ onBeforeNavigateNotSampled(transactionName) {
92
+ logger.log(`[ReactRouterV6Instrumentation] Will not send transaction "${transactionName}" due to beforeNavigate.`);
93
+ }
94
+ wrapUseRoutes = (origUseRoutes) => {
95
+ if (!this.useEffect || !this.useLocation || !this.matchRoutes) {
96
+ logger.warn("ReactRouterV6Instrumentation was unable to wrap `useRoutes` because of one or more missing parameters.");
97
+ return origUseRoutes;
98
+ }
99
+ let isMountRenderPass = true;
100
+ const useRoutes = (routes, locationArg) => {
101
+ const SentryRoutes = () => {
102
+ const Routes = origUseRoutes(routes, locationArg);
103
+ const location = this.useLocation();
104
+ const stableLocationParam = typeof locationArg === "string" || (locationArg && locationArg.pathname)
105
+ ? locationArg
106
+ : location;
107
+ this.useEffect(() => {
108
+ const normalizedLocation = typeof stableLocationParam === "string" ? { pathname: stableLocationParam } : stableLocationParam;
109
+ if (isMountRenderPass) {
110
+ this.onRouteChange(normalizedLocation, routes, true);
111
+ isMountRenderPass = false;
112
+ }
113
+ else {
114
+ this.onRouteChange(normalizedLocation, routes);
115
+ }
116
+ }, [stableLocationParam]);
117
+ return Routes;
118
+ };
119
+ return React.createElement(SentryRoutes, null);
120
+ };
121
+ return useRoutes;
122
+ };
123
+ }
124
+ const INITIAL_TRANSACTION_CONTEXT = {
125
+ name: "App Launch",
126
+ op: "navigation",
127
+ tags: {
128
+ ["routing.instrumentation"]: NativeReactRouterV6Instrumentation.instrumentationName,
129
+ },
130
+ };
131
+ export { NativeReactRouterV6Instrumentation };
@@ -0,0 +1,3 @@
1
+ import { Location } from "../types";
2
+ declare const stripFirstSlugFromLocation: (locationArg: string | Location) => Location;
3
+ export { stripFirstSlugFromLocation };
@@ -0,0 +1,5 @@
1
+ // Remove the location's first path ("/checkout"). Otherwise it won't match the proper route.
2
+ const stripFirstSlugFromLocation = (locationArg) => ({
3
+ pathname: (typeof locationArg === "string" ? locationArg : locationArg?.pathname || "").replace(/^\/\w+/, ""),
4
+ });
5
+ export { stripFirstSlugFromLocation };
@@ -0,0 +1,12 @@
1
+ import { RouteMatch, RouteObject } from "react-router-native";
2
+ import { Location } from "../types";
3
+ interface NormalizedNameAndMatchForLocationFunctionArgs {
4
+ readonly routes?: RouteObject[];
5
+ readonly location: Location;
6
+ readonly branches: RouteMatch[];
7
+ }
8
+ interface NormalizedNameAndMatchForLocationFunction {
9
+ (args: NormalizedNameAndMatchForLocationFunctionArgs): [string, RouteMatch | null];
10
+ }
11
+ declare const normalizedNameAndMatchForLocation: NormalizedNameAndMatchForLocationFunction;
12
+ export { normalizedNameAndMatchForLocation };
@@ -0,0 +1,34 @@
1
+ import { getNumberOfUrlSegments } from "@sentry/utils";
2
+ const normalizedNameAndMatchForLocation = ({ routes, location, branches, }) => {
3
+ if (!routes || routes.length === 0) {
4
+ return [location.pathname, null];
5
+ }
6
+ let pathBuilder = "";
7
+ if (branches) {
8
+ // eslint-disable-next-line @typescript-eslint/prefer-for-of
9
+ for (let x = 0; x < branches.length; x++) {
10
+ const branch = branches[x];
11
+ const route = branch.route;
12
+ if (route) {
13
+ // Early return if index route
14
+ if (route.index) {
15
+ return [branch.pathname, branch];
16
+ }
17
+ const path = route.path;
18
+ if (path) {
19
+ const newPath = path[0] === "/" || pathBuilder[pathBuilder.length - 1] === "/" ? path : `/${path}`;
20
+ pathBuilder += newPath;
21
+ if (branch.pathname === location.pathname) {
22
+ if (getNumberOfUrlSegments(pathBuilder) !== getNumberOfUrlSegments(branch.pathname) &&
23
+ pathBuilder.slice(-2) !== "/*") {
24
+ return [newPath, branch];
25
+ }
26
+ return [pathBuilder, branch];
27
+ }
28
+ }
29
+ }
30
+ }
31
+ }
32
+ return [location.pathname, null];
33
+ };
34
+ export { normalizedNameAndMatchForLocation };
@@ -0,0 +1,15 @@
1
+ import { Transaction, TransactionContext } from "@sentry/types";
2
+ import { Location, MatchRoutes, UseEffect, UseLocation, UseNavigationType, WrapUseRoutes } from "../types";
3
+ interface ReactRouterV6InstrumentationFunctionArgs {
4
+ readonly useEffect: UseEffect;
5
+ readonly useLocation: UseLocation;
6
+ readonly useNavigationType: UseNavigationType;
7
+ readonly matchRoutes: MatchRoutes;
8
+ readonly transformLocation?: (location: Location) => Location;
9
+ }
10
+ interface ReactRouterV6InstrumentationFunction {
11
+ (args: ReactRouterV6InstrumentationFunctionArgs): (customStartTransaction: (context: TransactionContext) => Transaction | undefined, startTransactionOnPageLoad?: boolean, startTransactionOnLocationChange?: boolean) => void;
12
+ }
13
+ declare const reactRouterV6Instrumentation: ReactRouterV6InstrumentationFunction;
14
+ declare const wrapUseRoutes: WrapUseRoutes;
15
+ export { reactRouterV6Instrumentation, wrapUseRoutes };
@@ -0,0 +1,92 @@
1
+ import { WINDOW } from "@sentry/browser";
2
+ import { logger } from "@sentry/utils";
3
+ import React from "react";
4
+ import { stripFirstSlugFromLocation } from "./location";
5
+ import { normalizedNameAndMatchForLocation } from "./normalizedNameAndMatchForLocation";
6
+ const transactionContext = ({ instrumentationName, op, routeName, source, }) => ({
7
+ name: routeName,
8
+ op,
9
+ tags: {
10
+ ["routing.instrumentation"]: instrumentationName,
11
+ ["routing.route.name"]: routeName,
12
+ },
13
+ metadata: {
14
+ source,
15
+ },
16
+ });
17
+ const instrumentationName = "react-router-v6";
18
+ let activeTransaction;
19
+ /* eslint-disable @typescript-eslint/naming-convention */
20
+ let _useEffect;
21
+ let _useLocation;
22
+ let _useNavigationType;
23
+ let _matchRoutes;
24
+ let _customStartTransaction;
25
+ let _startTransactionOnLocationChange;
26
+ let _transformLocation;
27
+ const reactRouterV6Instrumentation = ({ useEffect, useLocation, useNavigationType, matchRoutes, transformLocation = stripFirstSlugFromLocation, }) => {
28
+ return (customStartTransaction, startTransactionOnPageLoad = true, startTransactionOnLocationChange = true) => {
29
+ const initPathName = WINDOW && WINDOW.location && WINDOW.location.pathname;
30
+ if (startTransactionOnPageLoad && initPathName) {
31
+ activeTransaction = customStartTransaction(transactionContext({ instrumentationName, op: "pageload", routeName: initPathName, source: "url" }));
32
+ }
33
+ _useEffect = useEffect;
34
+ _useLocation = useLocation;
35
+ _useNavigationType = useNavigationType;
36
+ _matchRoutes = matchRoutes;
37
+ _customStartTransaction = customStartTransaction;
38
+ _startTransactionOnLocationChange = startTransactionOnLocationChange;
39
+ _transformLocation = transformLocation;
40
+ };
41
+ };
42
+ const updatePageloadTransaction = (location, routes) => {
43
+ const branches = _matchRoutes(routes, location);
44
+ if (activeTransaction && branches) {
45
+ const [name, match] = normalizedNameAndMatchForLocation({ routes, location, branches });
46
+ const source = match ? "route" : "url";
47
+ activeTransaction.setName(name, source);
48
+ }
49
+ };
50
+ const handleNavigation = (location, routes, navigationType) => {
51
+ const branches = _matchRoutes(routes, location);
52
+ if (_startTransactionOnLocationChange && (navigationType === "PUSH" || navigationType === "POP") && branches) {
53
+ if (activeTransaction) {
54
+ activeTransaction.finish();
55
+ }
56
+ const [name, match] = normalizedNameAndMatchForLocation({ routes, location, branches });
57
+ const source = match ? "route" : "url";
58
+ activeTransaction = _customStartTransaction(transactionContext({ instrumentationName, op: "navigation", routeName: name, source }));
59
+ }
60
+ };
61
+ const wrapUseRoutes = (origUseRoutes) => {
62
+ if (!_useEffect || !_useLocation || !_useNavigationType || !_matchRoutes || !_customStartTransaction) {
63
+ logger.warn("reactRouterV6Instrumentation was unable to wrap `useRoutes` because of one or more missing parameters.");
64
+ return origUseRoutes;
65
+ }
66
+ let isMountRenderPass = true;
67
+ // eslint-disable-next-line react/display-name
68
+ return (routes, locationArg) => {
69
+ const SentryRoutes = () => {
70
+ const Routes = origUseRoutes(routes, locationArg);
71
+ const location = _useLocation();
72
+ const navigationType = _useNavigationType();
73
+ // A value with stable identity to either pick `locationArg` if available or `location` if not
74
+ const stableLocationParam = typeof locationArg === "string" || (locationArg && locationArg.pathname)
75
+ ? locationArg
76
+ : location;
77
+ _useEffect(() => {
78
+ const normalizedLocation = typeof stableLocationParam === "string" ? { pathname: stableLocationParam } : stableLocationParam;
79
+ if (isMountRenderPass) {
80
+ updatePageloadTransaction(_transformLocation(normalizedLocation), routes);
81
+ isMountRenderPass = false;
82
+ }
83
+ else {
84
+ handleNavigation(_transformLocation(normalizedLocation), routes, navigationType);
85
+ }
86
+ }, [navigationType, stableLocationParam]);
87
+ return Routes;
88
+ };
89
+ return React.createElement(SentryRoutes, null);
90
+ };
91
+ };
92
+ export { reactRouterV6Instrumentation, wrapUseRoutes };
@@ -0,0 +1,9 @@
1
+ interface NavigationRoute {
2
+ readonly name: string;
3
+ readonly key: string;
4
+ readonly params: Record<string, unknown>;
5
+ }
6
+ interface NavigationCurrentRoute extends NavigationRoute {
7
+ readonly hasBeenSeen: boolean;
8
+ }
9
+ export type { NavigationRoute, NavigationCurrentRoute };
@@ -0,0 +1,22 @@
1
+ import { Integration } from "@sentry/types";
2
+ import { ComponentType, useEffect } from "react";
3
+ import { matchRoutes, RouteObject, useLocation } from "react-router-native";
4
+ interface Location {
5
+ readonly pathname: string;
6
+ }
7
+ type UseEffect = typeof useEffect;
8
+ type UseLocation = typeof useLocation;
9
+ type MatchRoutes = typeof matchRoutes;
10
+ type NavigationType = "PUSH" | "REPLACE" | "POP";
11
+ type UseNavigationType = () => NavigationType;
12
+ type UseRoutes = (routes: RouteObject[], locationArg?: Partial<Location> | string) => React.ReactElement | null;
13
+ interface WrapUseRoutes {
14
+ (useRoutes: UseRoutes): UseRoutes;
15
+ }
16
+ interface WrapComponent {
17
+ <P>(Component: ComponentType<P>): ComponentType<P>;
18
+ }
19
+ interface Integrations {
20
+ (): Integration[];
21
+ }
22
+ export type { Location, Integrations, UseEffect, UseLocation, NavigationType, UseNavigationType, MatchRoutes, UseRoutes, WrapUseRoutes, WrapComponent, };
@@ -0,0 +1 @@
1
+ export {};
@@ -4,22 +4,14 @@ import React from "react";
4
4
  import { View } from "react-native";
5
5
  import { theme } from "../../../../../infrastructure/ui/theme/theme";
6
6
  import { style } from "./Field.style";
7
- const { spaceM } = theme();
7
+ const { spaceM, spaceXL } = theme();
8
8
  const Field = ({ label, isFocused = false, style: customStyle }) => {
9
- const springs = useSpring(isFocused ? { scale: 0.75, translateY: -14, translateX: 0 } : { scale: 1, translateY: spaceM, translateX: spaceM });
9
+ const springs = useSpring(isFocused
10
+ ? { scale: 0.75, translateY: -14, translateX: -spaceXL }
11
+ : { scale: 1, translateY: spaceM, translateX: 0 });
10
12
  return (React.createElement(animated.View, { pointerEvents: "none", style: [
11
13
  {
12
- transform: [
13
- {
14
- scale: springs.scale,
15
- },
16
- {
17
- translateY: springs.translateY,
18
- },
19
- {
20
- translateX: springs.translateX,
21
- },
22
- ],
14
+ transform: [{ scale: springs.scale }, { translateY: springs.translateY }, { translateX: springs.translateX }],
23
15
  },
24
16
  customStyle?.field,
25
17
  ] },
@@ -1,6 +1,6 @@
1
1
  import { StyleSheet } from "react-native";
2
2
  import { theme } from "../../../../../infrastructure/ui/theme/theme";
3
- const { colorBase, spaceS } = theme();
3
+ const { colorBase, spaceM } = theme();
4
4
  const style = StyleSheet.create({
5
5
  fieldBackground: {
6
6
  backgroundColor: colorBase,
@@ -12,7 +12,7 @@ const style = StyleSheet.create({
12
12
  fieldText: {
13
13
  flexWrap: "nowrap",
14
14
  overflow: "hidden",
15
- paddingHorizontal: spaceS,
15
+ paddingHorizontal: spaceM,
16
16
  zIndex: 1,
17
17
  },
18
18
  });
@@ -7,8 +7,8 @@ import { Icon } from "../../atoms/icon/Icon";
7
7
  import { Input } from "../../atoms/input/Input";
8
8
  import { style } from "./InputField.style";
9
9
  const { colorBase, colorContent, colorGrayscaleL, colorPrimary, spaceM, iconSize } = theme();
10
- const inputPaddingRightWithIcon = iconSize + spaceM * 2;
11
- const inputPaddingRightWithoutIcon = spaceM * 2;
10
+ const inputPaddingRightWithIcon = iconSize + spaceM;
11
+ const inputPaddingRightWithoutIcon = spaceM;
12
12
  const InputField = ({ label, placeholder, value, multiline = false, minHeight, error, style: customStyle, onChange = () => void 0, icon, ...inputRestProps }) => {
13
13
  const [isFocused, setIsFocused] = useState(false);
14
14
  const handleOnChange = useCallback((text) => onChange(text), [onChange]);
@@ -5,6 +5,7 @@ declare const style: {
5
5
  };
6
6
  field: {
7
7
  position: "absolute";
8
+ width: string;
8
9
  zIndex: number;
9
10
  };
10
11
  icon: {
@@ -8,6 +8,7 @@ const style = StyleSheet.create({
8
8
  },
9
9
  field: {
10
10
  position: "absolute",
11
+ width: "100%",
11
12
  zIndex: 4,
12
13
  },
13
14
  icon: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lookiero/checkout",
3
- "version": "0.6.4",
3
+ "version": "0.7.1",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [
@@ -33,6 +33,7 @@
33
33
  "@lookiero/messaging": "^8.0.0",
34
34
  "@lookiero/messaging-react": "^8.0.0",
35
35
  "@react-spring/native": "^9.5.5",
36
+ "@sentry/react-native": "^4.13.0",
36
37
  "inline-style-prefixer": "6.0.1",
37
38
  "react-native-safe-area-context": "^4.4.1",
38
39
  "react-native-svg": "^12.1.1",
@@ -1,10 +0,0 @@
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 };
@@ -1,11 +0,0 @@
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 };
@@ -1,6 +0,0 @@
1
- import { QueryStatus } from "@lookiero/messaging-react";
2
- interface UseShouldIntroBeShownFunction {
3
- (): [boolean, QueryStatus];
4
- }
5
- declare const useShouldIntroBeShown: UseShouldIntroBeShownFunction;
6
- export { useShouldIntroBeShown };
@@ -1,7 +0,0 @@
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 };
@@ -1,6 +0,0 @@
1
- import { QueryStatus } from "@lookiero/messaging-react";
2
- interface UseViewIntroShownCountFunction {
3
- (): [number, QueryStatus];
4
- }
5
- declare const useViewIntroShownCount: UseViewIntroShownCountFunction;
6
- export { useViewIntroShownCount };
@@ -1,9 +0,0 @@
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 };
@@ -1,6 +0,0 @@
1
- import { FC } from "react";
2
- type IntroProps = {
3
- readonly customerId: string;
4
- };
5
- declare const Intro: FC<IntroProps>;
6
- export { Intro };
@@ -1,52 +0,0 @@
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 };
@@ -1,52 +0,0 @@
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 };