@lookiero/checkout 0.8.26 → 0.8.27

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.
@@ -3,12 +3,14 @@ import { CheckoutFeedbackProjection } from "../../../../../../projection/checkou
3
3
  interface OnChangeCheckoutQuestionFeedbackFunctionArgs {
4
4
  readonly checkoutQuestionId: string;
5
5
  readonly checkoutQuestionFeedback: string | undefined;
6
+ readonly hasFeedback?: boolean;
6
7
  }
7
8
  interface OnChangeCheckoutQuestionFeedbackFunction {
8
9
  (args: OnChangeCheckoutQuestionFeedbackFunctionArgs): void;
9
10
  }
10
11
  interface CheckoutQuestionFeedbackContextProviderProps {
11
12
  readonly feedback: CheckoutFeedbackProjection | undefined;
13
+ readonly onChanged?: OnChangeCheckoutQuestionFeedbackFunction;
12
14
  readonly children: ReactNode;
13
15
  }
14
16
  declare const CheckoutQuestionFeedbackProvider: FC<CheckoutQuestionFeedbackContextProviderProps>;
@@ -1,11 +1,18 @@
1
1
  import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react";
2
2
  import invariant from "tiny-invariant";
3
3
  const CheckoutQuestionFeedbackContext = createContext(null);
4
- const CheckoutQuestionFeedbackProvider = ({ feedback = {}, children, }) => {
4
+ const CheckoutQuestionFeedbackProvider = ({ feedback = {}, onChanged, children, }) => {
5
5
  const [contextFeedback, setContextFeedback] = useState(feedback);
6
- const onChange = useCallback(({ checkoutQuestionId, checkoutQuestionFeedback }) => setContextFeedback((feedback) => checkoutQuestionFeedback
7
- ? { ...feedback, [checkoutQuestionId]: checkoutQuestionFeedback }
8
- : Object.entries(feedback).reduce((acc, [id, feedback]) => (id !== checkoutQuestionId ? { ...acc, [id]: feedback } : acc), {})), []);
6
+ const onChange = useCallback(({ checkoutQuestionId, checkoutQuestionFeedback }) => {
7
+ setContextFeedback((feedback) => checkoutQuestionFeedback
8
+ ? { ...feedback, [checkoutQuestionId]: checkoutQuestionFeedback }
9
+ : Object.entries(feedback).reduce((acc, [id, feedback]) => (id !== checkoutQuestionId ? { ...acc, [id]: feedback } : acc), {}));
10
+ onChanged?.({
11
+ checkoutQuestionId,
12
+ checkoutQuestionFeedback,
13
+ hasFeedback: Boolean(contextFeedback[checkoutQuestionId]),
14
+ });
15
+ }, [contextFeedback, onChanged]);
9
16
  useEffect(() => setContextFeedback(feedback), [feedback]);
10
17
  const value = useMemo(() => ({
11
18
  feedback: contextFeedback,
@@ -1,8 +1,11 @@
1
1
  import { CommandStatus, QueryStatus } from "@lookiero/messaging-react";
2
2
  import React, { useCallback, useEffect, useRef } from "react";
3
3
  import { Platform } from "react-native";
4
+ import { CheckoutQuestionType } from "../../../../projection/checkoutQuestion/checkoutQuestion";
4
5
  import { useLogger } from "../../../../shared/logging/useLogger";
6
+ import { useTrackChangeFeedback } from "../../../../shared/tracking/infrastructure/useTrackChangeFeedback";
5
7
  import { useTrackPageView } from "../../../../shared/tracking/infrastructure/useTrackPageView";
8
+ import { useTrackPressContinue } from "../../../../shared/tracking/infrastructure/useTrackPressContinue";
6
9
  import { Spinner } from "../../../../shared/ui/components/atoms/spinner/Spinner";
7
10
  import { useGiveCheckoutFeedback } from "../../../domain/checkoutFeedback/react/useGiveCheckoutFeedback";
8
11
  import { useViewFirstAvailableCheckoutByCustomerId } from "../../../projection/checkout/react/useViewFirstAvailableCheckoutByCustomerId";
@@ -20,23 +23,45 @@ const Feedback = ({ customerId, country }) => {
20
23
  const [checkoutQuestions, checkoutQuestionsStatus] = useListCheckoutQuestionsByCheckoutId({
21
24
  checkoutId: checkout?.id,
22
25
  });
26
+ useTrackPageView({
27
+ page: TrackingPage.FEEDBACK,
28
+ country,
29
+ checkoutId: checkout?.id,
30
+ });
31
+ const trackChangeFeedback = useTrackChangeFeedback({
32
+ page: TrackingPage.FEEDBACK,
33
+ country,
34
+ checkoutId: checkout?.id,
35
+ });
36
+ const handleOnChangedFeedback = useCallback(({ checkoutQuestionId, checkoutQuestionFeedback, hasFeedback }) => {
37
+ const question = checkoutQuestions?.find((question) => question.id === checkoutQuestionId);
38
+ if (question?.type === CheckoutQuestionType.HOST_TEXTAREA && hasFeedback) {
39
+ return;
40
+ }
41
+ trackChangeFeedback({
42
+ questionId: checkoutQuestionId,
43
+ questionName: question?.name,
44
+ feedback: checkoutQuestionFeedback,
45
+ });
46
+ }, [checkoutQuestions, trackChangeFeedback]);
23
47
  const [giveCheckoutFeedback, giveCheckoutFeedbackStatus] = useGiveCheckoutFeedback({
24
48
  checkoutId: checkout?.id,
25
49
  logger,
26
50
  });
27
51
  const checkoutFeedbackGivenRef = useRef(false);
52
+ const trackPressContinue = useTrackPressContinue({
53
+ page: TrackingPage.FEEDBACK,
54
+ country,
55
+ checkoutId: checkout?.id,
56
+ });
28
57
  const handleOnSubmit = useCallback(async (feedbacks) => {
29
58
  try {
59
+ trackPressContinue();
30
60
  await giveCheckoutFeedback({ feedbacks });
31
61
  checkoutFeedbackGivenRef.current = true;
32
62
  }
33
63
  catch (e) { }
34
- }, [giveCheckoutFeedback]);
35
- useTrackPageView({
36
- page: TrackingPage.FEEDBACK,
37
- country,
38
- checkoutId: checkout?.id,
39
- });
64
+ }, [giveCheckoutFeedback, trackPressContinue]);
40
65
  /**
41
66
  * Give empty feedback when this view is unmounted
42
67
  * (if feedback has not already been given)
@@ -50,7 +75,7 @@ const Feedback = ({ customerId, country }) => {
50
75
  const dependenciesLoaded = dependenciesLoadedStatuses.includes(checkoutStatus) && dependenciesLoadedStatuses.includes(checkoutQuestionsStatus);
51
76
  if (!dependenciesLoaded)
52
77
  return React.createElement(Spinner, null);
53
- return (React.createElement(CheckoutQuestionFeedbackProvider, { feedback: {} },
78
+ return (React.createElement(CheckoutQuestionFeedbackProvider, { feedback: {}, onChanged: handleOnChangedFeedback },
54
79
  React.createElement(SafeAreaScrollView, { scrollerPaddingTop: Platform.OS === "web" || Platform.OS === "android" ? HEADER_HEIGHT : 0 },
55
80
  React.createElement(Body, { style: { column: style.bodyColumn } },
56
81
  React.createElement(CheckoutQuestionsForm, { checkoutQuestions: checkoutQuestions || [], submitButtonDisabled: giveCheckoutFeedbackStatus === CommandStatus.LOADING, onSubmit: handleOnSubmit })))));
@@ -0,0 +1,20 @@
1
+ import { TrackingPage } from "../../../infrastructure/tracking/tracking";
2
+ import { Country } from "../../../projection/shared/country";
3
+ interface ChangeFeedbackFunctionArgs {
4
+ readonly questionId: string;
5
+ readonly questionName: string;
6
+ readonly feedback: string | undefined;
7
+ }
8
+ interface ChangeFeedbackFunction {
9
+ (args: ChangeFeedbackFunctionArgs): void;
10
+ }
11
+ interface UseTrackChangeFeedbackArgs {
12
+ readonly page: TrackingPage;
13
+ readonly country: Country;
14
+ readonly checkoutId?: string;
15
+ }
16
+ interface UseTrackChangeFeedback {
17
+ (agrs: UseTrackChangeFeedbackArgs): ChangeFeedbackFunction;
18
+ }
19
+ declare const useTrackChangeFeedback: UseTrackChangeFeedback;
20
+ export { useTrackChangeFeedback };
@@ -0,0 +1,25 @@
1
+ import { useCallback } from "react";
2
+ import { PROJECT } from "../../../infrastructure/tracking/tracking";
3
+ import { TrackingEvent, TrackingEventCategory } from "../tracking";
4
+ import { useEmitUserEvent } from "./useEmitUserEvent";
5
+ const useTrackChangeFeedback = ({ page, country, checkoutId }) => {
6
+ const emitUserEvent = useEmitUserEvent();
7
+ const changeFeedback = useCallback(({ questionId, questionName, feedback }) => {
8
+ if (!checkoutId) {
9
+ return;
10
+ }
11
+ const changeFeedbackTrackingEvent = {
12
+ event: TrackingEvent.CHANGE_FEEDBACK,
13
+ eventCategory: TrackingEventCategory.NAVIGATION,
14
+ section: `${PROJECT}_${page}`,
15
+ store: country,
16
+ checkoutId,
17
+ questionId,
18
+ questionName,
19
+ feedback,
20
+ };
21
+ emitUserEvent(changeFeedbackTrackingEvent);
22
+ }, [checkoutId, country, emitUserEvent, page]);
23
+ return changeFeedback;
24
+ };
25
+ export { useTrackChangeFeedback };
@@ -10,7 +10,8 @@ declare enum TrackingEvent {
10
10
  PRESS_PRICING = "press-pricing",
11
11
  PRESS_ITEM = "press-item",
12
12
  PRESS_CONTINUE = "press-continue",
13
- TAB_VIEW = "tab-view"
13
+ TAB_VIEW = "tab-view",
14
+ CHANGE_FEEDBACK = "change-feedback"
14
15
  }
15
16
  declare enum TrackingEventCategory {
16
17
  NAVIGATION = "navigation"
@@ -58,5 +59,10 @@ type PressContinueTrackingEvent = BaseTrackingEvent;
58
59
  interface TabViewTrackingEvent<T> extends BaseTrackingEvent {
59
60
  readonly tab: T;
60
61
  }
61
- export type { BaseTrackingEvent, ImageViewTrackingEvent, ItemPageViewTrackingEvent, KeepItemTrackingEvent, PageViewTrackingEvent, PressContinueTrackingEvent, PressItemTrackingEvent, PressPricingTrackingEvent, ReplaceItemTrackingEvent, ResetItemTrackingEvent, ReturnItemTrackingEvent, TabViewTrackingEvent, };
62
+ interface ChangeFeedbackTrackingEvent extends BaseTrackingEvent {
63
+ readonly questionId: string;
64
+ readonly questionName: string;
65
+ readonly feedback: string | undefined;
66
+ }
67
+ export type { BaseTrackingEvent, ChangeFeedbackTrackingEvent, ImageViewTrackingEvent, ItemPageViewTrackingEvent, KeepItemTrackingEvent, PageViewTrackingEvent, PressContinueTrackingEvent, PressItemTrackingEvent, PressPricingTrackingEvent, ReplaceItemTrackingEvent, ResetItemTrackingEvent, ReturnItemTrackingEvent, TabViewTrackingEvent, };
62
68
  export { TrackingEvent, TrackingEventCategory };
@@ -10,6 +10,7 @@ var TrackingEvent;
10
10
  TrackingEvent["PRESS_ITEM"] = "press-item";
11
11
  TrackingEvent["PRESS_CONTINUE"] = "press-continue";
12
12
  TrackingEvent["TAB_VIEW"] = "tab-view";
13
+ TrackingEvent["CHANGE_FEEDBACK"] = "change-feedback";
13
14
  })(TrackingEvent || (TrackingEvent = {}));
14
15
  var TrackingEventCategory;
15
16
  (function (TrackingEventCategory) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lookiero/checkout",
3
- "version": "0.8.26",
3
+ "version": "0.8.27",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [