@lookiero/checkout 0.2.40 → 0.2.42

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 (40) hide show
  1. package/dist/domain/checkoutItem/command/returnCheckoutItem.d.ts +15 -0
  2. package/dist/domain/checkoutItem/command/returnCheckoutItem.js +7 -0
  3. package/dist/domain/checkoutItem/model/checkoutItem.d.ts +5 -1
  4. package/dist/domain/checkoutItem/model/checkoutItem.js +11 -1
  5. package/dist/domain/checkoutItem/model/checkoutItemReturned.d.ts +13 -0
  6. package/dist/domain/checkoutItem/model/checkoutItemReturned.js +4 -0
  7. package/dist/domain/checkoutItem/model/feedbacks.d.ts +3 -0
  8. package/dist/domain/checkoutItem/model/feedbacks.js +1 -0
  9. package/dist/infrastructure/delivery/baseBootstrap.js +3 -1
  10. package/dist/infrastructure/delivery/mock/dataSourceCheckoutItems.js +2 -1
  11. package/dist/infrastructure/domain/checkout/model/httpCheckouts.js +1 -3
  12. package/dist/infrastructure/domain/checkout/model/httpCheckoutsStart.js +1 -1
  13. package/dist/infrastructure/domain/checkout/react/useStartCheckout.js +1 -1
  14. package/dist/infrastructure/domain/checkoutBooking/model/httpCheckoutBookings.js +1 -3
  15. package/dist/infrastructure/domain/checkoutBooking/model/httpCheckoutBookingsBook.js +2 -2
  16. package/dist/infrastructure/domain/checkoutBooking/react/useBookCheckouBookingForCheckoutItem.js +1 -1
  17. package/dist/infrastructure/domain/checkoutItem/model/httpCheckoutItems.js +6 -1
  18. package/dist/infrastructure/domain/checkoutItem/model/httpCheckoutItemsKeep.js +1 -1
  19. package/dist/infrastructure/domain/checkoutItem/model/httpCheckoutItemsReturn.d.ts +5 -0
  20. package/dist/infrastructure/domain/checkoutItem/model/httpCheckoutItemsReturn.js +13 -0
  21. package/dist/infrastructure/domain/checkoutItem/react/useKeepCheckoutItem.js +1 -1
  22. package/dist/infrastructure/domain/checkoutItem/react/useReturnCheckoutItem.d.ts +17 -0
  23. package/dist/infrastructure/domain/checkoutItem/react/useReturnCheckoutItem.js +13 -0
  24. package/dist/infrastructure/domain/uiSetting/react/useUpdateUiSetting.js +1 -1
  25. package/dist/infrastructure/projection/checkout/react/useViewFirstAvailableCheckoutByCustomerId.js +5 -0
  26. package/dist/infrastructure/ui/shared/components/molecules/inputField/InputField.d.ts +1 -0
  27. package/dist/infrastructure/ui/shared/components/molecules/inputField/InputField.style.js +2 -2
  28. package/dist/infrastructure/ui/shared/components/molecules/selectField/SelectField.d.ts +2 -0
  29. package/dist/infrastructure/ui/shared/components/molecules/selectField/SelectField.js +1 -1
  30. package/dist/infrastructure/ui/views/item/Item.js +28 -11
  31. package/dist/infrastructure/ui/views/item/components/banner/CustomerDecissionBanner.d.ts +3 -2
  32. package/dist/infrastructure/ui/views/item/components/itemActions/ItemActions.d.ts +3 -0
  33. package/dist/infrastructure/ui/views/item/components/itemActions/ItemActions.js +11 -5
  34. package/dist/infrastructure/ui/views/item/components/itemActions/ItemActions.style.d.ts +3 -0
  35. package/dist/infrastructure/ui/views/item/components/itemActions/ItemActions.style.js +4 -1
  36. package/dist/infrastructure/ui/views/item/components/returnQuestionsForm/ReturnQuestionsForm.d.ts +1 -1
  37. package/dist/infrastructure/ui/views/item/components/returnQuestionsForm/ReturnQuestionsForm.js +3 -2
  38. package/dist/infrastructure/ui/views/summary/Summary.js +2 -5
  39. package/dist/projection/checkoutItem/checkoutItem.d.ts +1 -1
  40. package/package.json +1 -1
@@ -0,0 +1,15 @@
1
+ import { Command } from "@lookiero/messaging";
2
+ import { Feedbacks } from "../model/feedbacks";
3
+ declare const RETURN_CHECKOUT_ITEM = "return_checkout_item";
4
+ interface ReturnCheckoutItemPayload {
5
+ readonly aggregateId: string;
6
+ readonly feedbacks: Feedbacks;
7
+ }
8
+ interface ReturnCheckoutItem extends Command<typeof RETURN_CHECKOUT_ITEM>, ReturnCheckoutItemPayload {
9
+ }
10
+ interface ReturnCheckoutItemFunction {
11
+ (payload: ReturnCheckoutItemPayload): ReturnCheckoutItem;
12
+ }
13
+ declare const returnCheckoutItem: ReturnCheckoutItemFunction;
14
+ export type { ReturnCheckoutItem };
15
+ export { RETURN_CHECKOUT_ITEM, returnCheckoutItem };
@@ -0,0 +1,7 @@
1
+ import { command } from "@lookiero/messaging";
2
+ const RETURN_CHECKOUT_ITEM = "return_checkout_item";
3
+ const returnCheckoutItem = ({ aggregateId, ...payload }) => ({
4
+ ...command({ aggregateId, name: RETURN_CHECKOUT_ITEM }),
5
+ ...payload,
6
+ });
7
+ export { RETURN_CHECKOUT_ITEM, returnCheckoutItem };
@@ -1,5 +1,7 @@
1
1
  import { AggregateRoot, CommandHandlerFunction } from "@lookiero/messaging";
2
2
  import { KeepCheckoutItem } from "../command/keepCheckoutItem";
3
+ import { ReturnCheckoutItem } from "../command/returnCheckoutItem";
4
+ import { Feedbacks } from "./feedbacks";
3
5
  import { Price } from "./price";
4
6
  declare enum CheckoutItemStatus {
5
7
  INITIAL = "INITIAL",
@@ -11,7 +13,9 @@ declare enum CheckoutItemStatus {
11
13
  interface CheckoutItem extends AggregateRoot {
12
14
  readonly status: CheckoutItemStatus;
13
15
  readonly price: Price;
16
+ readonly feedbacks: Feedbacks;
14
17
  }
15
18
  declare const keepCheckoutItemHandler: CommandHandlerFunction<KeepCheckoutItem, CheckoutItem>;
19
+ declare const returnCheckoutItemHandler: CommandHandlerFunction<ReturnCheckoutItem, CheckoutItem>;
16
20
  export type { CheckoutItem };
17
- export { CheckoutItemStatus, keepCheckoutItemHandler };
21
+ export { CheckoutItemStatus, keepCheckoutItemHandler, returnCheckoutItemHandler };
@@ -1,5 +1,6 @@
1
1
  import invariant from "tiny-invariant";
2
2
  import { checkoutItemKept } from "./checkoutItemKept";
3
+ import { checkoutItemReturned } from "./checkoutItemReturned";
3
4
  var CheckoutItemStatus;
4
5
  (function (CheckoutItemStatus) {
5
6
  CheckoutItemStatus["INITIAL"] = "INITIAL";
@@ -17,4 +18,13 @@ const keepCheckoutItemHandler = () => async ({ aggregateRoot, command }) => {
17
18
  domainEvents: [checkoutItemKept({ aggregateId })],
18
19
  };
19
20
  };
20
- export { CheckoutItemStatus, keepCheckoutItemHandler };
21
+ const returnCheckoutItemHandler = () => async ({ aggregateRoot, command }) => {
22
+ const { aggregateId } = command;
23
+ invariant(aggregateRoot.status !== CheckoutItemStatus.RETURNED, "CheckoutItem is already returned");
24
+ return {
25
+ ...aggregateRoot,
26
+ status: CheckoutItemStatus.RETURNED,
27
+ domainEvents: [checkoutItemReturned({ aggregateId })],
28
+ };
29
+ };
30
+ export { CheckoutItemStatus, keepCheckoutItemHandler, returnCheckoutItemHandler };
@@ -0,0 +1,13 @@
1
+ import { DomainEvent } from "@lookiero/messaging";
2
+ declare const CHECKOUT_ITEM_RETURNED = "checkout_item_returned";
3
+ interface CheckoutItemReturnedPayload {
4
+ readonly aggregateId: string;
5
+ }
6
+ interface CheckoutItemReturned extends DomainEvent<typeof CHECKOUT_ITEM_RETURNED>, CheckoutItemReturnedPayload {
7
+ }
8
+ interface CheckoutItemReturnedFunction {
9
+ (payload: CheckoutItemReturnedPayload): CheckoutItemReturned;
10
+ }
11
+ declare const checkoutItemReturned: CheckoutItemReturnedFunction;
12
+ export type { CheckoutItemReturned };
13
+ export { CHECKOUT_ITEM_RETURNED, checkoutItemReturned };
@@ -0,0 +1,4 @@
1
+ import { domainEvent } from "@lookiero/messaging";
2
+ const CHECKOUT_ITEM_RETURNED = "checkout_item_returned";
3
+ const checkoutItemReturned = ({ aggregateId }) => domainEvent({ aggregateId, name: CHECKOUT_ITEM_RETURNED });
4
+ export { CHECKOUT_ITEM_RETURNED, checkoutItemReturned };
@@ -0,0 +1,3 @@
1
+ declare type ReturnQuestionId = string;
2
+ declare type Feedbacks = Record<ReturnQuestionId, ReturnQuestionId | string>;
3
+ export type { Feedbacks };
@@ -0,0 +1 @@
1
+ export {};
@@ -4,7 +4,8 @@ import { startCheckoutHandler } from "../../domain/checkout/model/checkout";
4
4
  import { BOOK_CHECKOUT_BOOKING_FOR_CHECKOUT_ITEM } from "../../domain/checkoutBooking/command/bookCheckoutBookingForCheckoutItem";
5
5
  import { bookCheckoutBookingForCheckoutItemHandler, } from "../../domain/checkoutBooking/model/checkoutBooking";
6
6
  import { KEEP_CHECKOUT_ITEM } from "../../domain/checkoutItem/command/keepCheckoutItem";
7
- import { keepCheckoutItemHandler } from "../../domain/checkoutItem/model/checkoutItem";
7
+ import { RETURN_CHECKOUT_ITEM } from "../../domain/checkoutItem/command/returnCheckoutItem";
8
+ import { keepCheckoutItemHandler, returnCheckoutItemHandler, } from "../../domain/checkoutItem/model/checkoutItem";
8
9
  import { UPDATE_UI_SETTING } from "../../domain/uiSetting/command/updateUiSetting";
9
10
  import { updateUiSettingHandler } from "../../domain/uiSetting/model/uiSetting";
10
11
  import { viewBookedSizeChangeProductsVariantsForCheckoutItemHandler, VIEW_BOOKED_SIZE_CHANGE_PRODUCT_VARIANTS_FOR_CHECKOUT_ITEM, } from "../../projection/bookedSizeChangeProductsVariants/viewBookedSizeChangeProductVariantsForCheckoutItem";
@@ -39,6 +40,7 @@ const baseBootstrap = ({ checkoutByIdView, firstAvailableCheckoutByCustomerIdVie
39
40
  view: returnQuestionsByCheckoutItemIdView,
40
41
  })
41
42
  .command(KEEP_CHECKOUT_ITEM, keepCheckoutItemHandler)(getCheckoutItem, saveCheckoutItem, ...checkoutItemsDependencies)
43
+ .command(RETURN_CHECKOUT_ITEM, returnCheckoutItemHandler)(getCheckoutItem, saveCheckoutItem, ...checkoutItemsDependencies)
42
44
  .query(VIEW_BOOKED_SIZE_CHANGE_PRODUCT_VARIANTS_FOR_CHECKOUT_ITEM, viewBookedSizeChangeProductsVariantsForCheckoutItemHandler, {
43
45
  view: bookedSizeChangeProductsVariantsForCheckoutItemView,
44
46
  })
@@ -10,10 +10,11 @@ const toCheckoutItemProjection = (checkoutItem) => ({
10
10
  const toCheckoutItemDomain = (checkoutItem) => {
11
11
  invariant(checkoutItem, "No checkoutItem found!");
12
12
  return {
13
+ aggregateId: checkoutItem.id,
13
14
  id: checkoutItem.id,
14
15
  status: checkoutItem.status,
15
- aggregateId: checkoutItem.id,
16
16
  price: checkoutItem.price,
17
+ feedbacks: checkoutItem.feedback,
17
18
  domainEvents: [],
18
19
  };
19
20
  };
@@ -15,7 +15,5 @@ const toDomain = (checkout) => {
15
15
  };
16
16
  };
17
17
  const getCheckout = ({ queryBus }) => async (aggregateId) => toDomain(await queryBus(viewCheckoutById({ checkoutId: aggregateId })));
18
- const saveCheckout = ({ httpPost }) => async (aggregateRoot) => {
19
- await httpCheckoutsStart({ httpPost })(aggregateRoot);
20
- };
18
+ const saveCheckout = ({ httpPost }) => async (aggregateRoot) => await httpCheckoutsStart({ httpPost })(aggregateRoot);
21
19
  export { getCheckout, saveCheckout };
@@ -5,7 +5,7 @@ const httpCheckoutsStart = ({ httpPost }) => async ({ aggregateId, domainEvents
5
5
  if (!checkoutStarted) {
6
6
  return;
7
7
  }
8
- httpPost({
8
+ await httpPost({
9
9
  endpoint: "/start-checkout",
10
10
  body: { checkoutId: aggregateId },
11
11
  });
@@ -4,7 +4,7 @@ import { startCheckout } from "../../../../domain/checkout/command/startCheckout
4
4
  import { MESSAGING_CONTEXT_ID } from "../../../delivery/baseBootstrap";
5
5
  const useStartCheckout = ({ checkoutId }) => {
6
6
  const [commandBus, status] = useCommand({ contextId: MESSAGING_CONTEXT_ID });
7
- const start = useCallback(async () => await commandBus(startCheckout({ aggregateId: checkoutId })), [checkoutId, commandBus]);
7
+ const start = useCallback(() => commandBus(startCheckout({ aggregateId: checkoutId })), [checkoutId, commandBus]);
8
8
  return [start, status];
9
9
  };
10
10
  export { useStartCheckout };
@@ -11,7 +11,5 @@ const toDomain = (checkoutBooking) => {
11
11
  };
12
12
  };
13
13
  const getCheckoutBooking = ({ queryBus }) => async (aggregateId) => toDomain(await queryBus(viewCheckoutBookingById({ checkoutBookingId: aggregateId })));
14
- const saveCheckoutBooking = ({ httpPost }) => async (aggregateRoot) => {
15
- await httpCheckoutBookingsBook({ httpPost })(aggregateRoot);
16
- };
14
+ const saveCheckoutBooking = ({ httpPost }) => async (aggregateRoot) => await httpCheckoutBookingsBook({ httpPost })(aggregateRoot);
17
15
  export { getCheckoutBooking, saveCheckoutBooking };
@@ -6,8 +6,8 @@ const httpCheckoutBookingsBook = ({ httpPost }) => async ({ aggregateId, checkou
6
6
  return;
7
7
  }
8
8
  const { checkoutItemId } = checkoutBookingBooked;
9
- httpPost({
10
- endpoint: "/book-size-replaceable-product-variants-for-checkout-item",
9
+ await httpPost({
10
+ endpoint: "/book-size-change-product-variants-for-checkout-item",
11
11
  body: {
12
12
  checkoutId,
13
13
  checkoutItemId,
@@ -5,7 +5,7 @@ import { bookCheckoutBookingForCheckoutItem } from "../../../../domain/checkoutB
5
5
  import { MESSAGING_CONTEXT_ID } from "../../../delivery/baseBootstrap";
6
6
  const useBookCheckouBookingForCheckoutItem = ({ checkoutId, checkoutItemId, checkoutBookingId, }) => {
7
7
  const [commandBus, status] = useCommand({ contextId: MESSAGING_CONTEXT_ID });
8
- const book = useCallback(async () => await commandBus(bookCheckoutBookingForCheckoutItem({
8
+ const book = useCallback(() => commandBus(bookCheckoutBookingForCheckoutItem({
9
9
  aggregateId: checkoutBookingId || uuid(),
10
10
  checkoutId,
11
11
  checkoutItemId,
@@ -1,18 +1,23 @@
1
1
  import invariant from "tiny-invariant";
2
2
  import { viewCheckoutItemById, } from "../../../../projection/checkoutItem/viewCheckoutItemById";
3
3
  import { httpCheckoutItemsKeep } from "./httpCheckoutItemsKeep";
4
+ import { httpCheckoutItemsReturn } from "./httpCheckoutItemsReturn";
4
5
  const toDomain = (checkoutItem) => {
5
6
  invariant(checkoutItem, "No checkoutItem found!");
6
7
  return {
7
8
  id: checkoutItem.id,
8
9
  status: checkoutItem.status,
9
10
  price: checkoutItem.price,
11
+ feedbacks: checkoutItem.feedback,
10
12
  aggregateId: checkoutItem.id,
11
13
  domainEvents: [],
12
14
  };
13
15
  };
14
16
  const getCheckoutItem = ({ queryBus }) => async (aggregateId) => toDomain(await queryBus(viewCheckoutItemById({ checkoutItemId: aggregateId })));
15
17
  const saveCheckoutItem = ({ httpPost }) => async (aggregateRoot) => {
16
- await httpCheckoutItemsKeep({ httpPost })(aggregateRoot);
18
+ await Promise.all([
19
+ httpCheckoutItemsKeep({ httpPost })(aggregateRoot),
20
+ httpCheckoutItemsReturn({ httpPost })(aggregateRoot),
21
+ ]);
17
22
  };
18
23
  export { getCheckoutItem, saveCheckoutItem };
@@ -5,7 +5,7 @@ const httpCheckoutItemsKeep = ({ httpPost }) => async ({ aggregateId, domainEven
5
5
  if (!checkoutItemKept) {
6
6
  return;
7
7
  }
8
- httpPost({
8
+ await httpPost({
9
9
  endpoint: "/keep-checkout-item",
10
10
  body: { checkoutItemId: aggregateId },
11
11
  });
@@ -0,0 +1,5 @@
1
+ import { HttpCheckoutItemsSaveFunction } from "./httpCheckoutItems";
2
+ interface HttpCheckoutItemsReturnFunction extends HttpCheckoutItemsSaveFunction {
3
+ }
4
+ declare const httpCheckoutItemsReturn: HttpCheckoutItemsReturnFunction;
5
+ export { httpCheckoutItemsReturn };
@@ -0,0 +1,13 @@
1
+ import { CHECKOUT_ITEM_RETURNED, } from "../../../../domain/checkoutItem/model/checkoutItemReturned";
2
+ const isCheckoutItemReturned = (event) => event.name === CHECKOUT_ITEM_RETURNED;
3
+ const httpCheckoutItemsReturn = ({ httpPost }) => async ({ aggregateId, feedbacks, domainEvents }) => {
4
+ const checkoutItemReturned = domainEvents.find(isCheckoutItemReturned);
5
+ if (!checkoutItemReturned) {
6
+ return;
7
+ }
8
+ await httpPost({
9
+ endpoint: "/return-checkout-item",
10
+ body: { checkoutItemId: aggregateId, feedbacks },
11
+ });
12
+ };
13
+ export { httpCheckoutItemsReturn };
@@ -4,7 +4,7 @@ import { keepCheckoutItem } from "../../../../domain/checkoutItem/command/keepCh
4
4
  import { MESSAGING_CONTEXT_ID } from "../../../delivery/baseBootstrap";
5
5
  const useKeepCheckoutItem = ({ checkoutItemId }) => {
6
6
  const [commandBus, status] = useCommand({ contextId: MESSAGING_CONTEXT_ID });
7
- const keep = useCallback(async () => await commandBus(keepCheckoutItem({
7
+ const keep = useCallback(() => commandBus(keepCheckoutItem({
8
8
  aggregateId: checkoutItemId,
9
9
  })), [checkoutItemId, commandBus]);
10
10
  return [keep, status];
@@ -0,0 +1,17 @@
1
+ import { CommandStatus } from "@lookiero/messaging-react";
2
+ import { Feedbacks } from "../../../../domain/checkoutItem/model/feedbacks";
3
+ interface ReturnCheckoutItemFunctionArgs {
4
+ readonly feedbacks: Feedbacks;
5
+ }
6
+ interface ReturnCheckoutItemFunction {
7
+ (args: ReturnCheckoutItemFunctionArgs): Promise<void>;
8
+ }
9
+ interface UseReturnCheckoutItemFunctionArgs {
10
+ readonly checkoutItemId: string;
11
+ }
12
+ declare type UseReturnCheckoutItemResult = [returnCheckoutItem: ReturnCheckoutItemFunction, status: CommandStatus];
13
+ interface UseReturnCheckoutItemFunction {
14
+ (args: UseReturnCheckoutItemFunctionArgs): UseReturnCheckoutItemResult;
15
+ }
16
+ declare const useReturnCheckoutItem: UseReturnCheckoutItemFunction;
17
+ export { useReturnCheckoutItem };
@@ -0,0 +1,13 @@
1
+ import { useCommand } from "@lookiero/messaging-react";
2
+ import { useCallback } from "react";
3
+ import { returnCheckoutItem as returnCheckoutItemCommand } from "../../../../domain/checkoutItem/command/returnCheckoutItem";
4
+ import { MESSAGING_CONTEXT_ID } from "../../../delivery/baseBootstrap";
5
+ const useReturnCheckoutItem = ({ checkoutItemId }) => {
6
+ const [commandBus, status] = useCommand({ contextId: MESSAGING_CONTEXT_ID });
7
+ const returnCheckoutItem = useCallback(({ feedbacks }) => commandBus(returnCheckoutItemCommand({
8
+ aggregateId: checkoutItemId,
9
+ feedbacks,
10
+ })), [checkoutItemId, commandBus]);
11
+ return [returnCheckoutItem, status];
12
+ };
13
+ export { useReturnCheckoutItem };
@@ -5,7 +5,7 @@ import { updateUiSetting } from "../../../../domain/uiSetting/command/updateUiSe
5
5
  import { MESSAGING_CONTEXT_ID } from "../../../delivery/baseBootstrap";
6
6
  const useUpdateUiSetting = () => {
7
7
  const [commandBus, status] = useCommand({ contextId: MESSAGING_CONTEXT_ID });
8
- const update = useCallback(async ({ key, value }) => await commandBus(updateUiSetting({
8
+ const update = useCallback(({ key, value }) => commandBus(updateUiSetting({
9
9
  aggregateId: uuid(),
10
10
  key,
11
11
  value,
@@ -1,9 +1,14 @@
1
1
  import { useQuery } from "@lookiero/messaging-react";
2
+ import { CHECKOUT_ITEM_KEPT } from "../../../../domain/checkoutItem/model/checkoutItemKept";
3
+ import { CHECKOUT_ITEM_RETURNED, } from "../../../../domain/checkoutItem/model/checkoutItemReturned";
2
4
  import { viewFirstAvailableCheckoutByCustomerId } from "../../../../projection/checkout/viewFirstAvailableCheckoutByCustomerId";
3
5
  import { MESSAGING_CONTEXT_ID } from "../../../delivery/baseBootstrap";
6
+ const isCheckoutItemKept = (event) => event.name === CHECKOUT_ITEM_KEPT;
7
+ const isCheckoutItemReturned = (event) => event.name === CHECKOUT_ITEM_RETURNED;
4
8
  const useViewFirstAvailableCheckoutByCustomerId = ({ customerId }) => useQuery({
5
9
  query: viewFirstAvailableCheckoutByCustomerId({ customerId }),
6
10
  contextId: MESSAGING_CONTEXT_ID,
11
+ invalidation: isCheckoutItemKept || isCheckoutItemReturned,
7
12
  options: { staleTime: Infinity, retry: false, refetchOnWindowFocus: false },
8
13
  });
9
14
  export { useViewFirstAvailableCheckoutByCustomerId };
@@ -21,4 +21,5 @@ interface InputFieldBaseProps {
21
21
  interface InputFieldProps extends Omit<InputProps, keyof InputFieldBaseProps>, InputFieldBaseProps {
22
22
  }
23
23
  declare const InputField: FC<InputFieldProps>;
24
+ export type { InputFieldStyle };
24
25
  export { InputField };
@@ -1,6 +1,6 @@
1
1
  import { StyleSheet } from "react-native";
2
2
  import { theme } from "../../../../theme/theme";
3
- const { spaceXS, spaceM, spaceL } = theme();
3
+ const { spaceXS, spaceS, spaceM, spaceL } = theme();
4
4
  const style = StyleSheet.create({
5
5
  error: {
6
6
  marginLeft: spaceL,
@@ -12,7 +12,7 @@ const style = StyleSheet.create({
12
12
  },
13
13
  icon: {
14
14
  position: "absolute",
15
- right: spaceM,
15
+ right: spaceS,
16
16
  top: spaceM,
17
17
  zIndex: 4,
18
18
  },
@@ -1,10 +1,12 @@
1
1
  import { FC } from "react";
2
2
  import { StyleProp, TextStyle, TouchableHighlightProps, ViewStyle } from "react-native";
3
+ import { InputFieldStyle } from "../inputField/InputField";
3
4
  interface SelectFieldStyle {
4
5
  readonly selectField: StyleProp<ViewStyle>;
5
6
  readonly modalContent: StyleProp<ViewStyle>;
6
7
  readonly option: StyleProp<ViewStyle>;
7
8
  readonly optionText: StyleProp<TextStyle>;
9
+ readonly inputField: Partial<InputFieldStyle>;
8
10
  }
9
11
  interface Option {
10
12
  readonly label: string;
@@ -18,7 +18,7 @@ const SelectField = ({ placeholder, value, options, style: customStyle, onChange
18
18
  return (React.createElement(React.Fragment, null,
19
19
  React.createElement(TouchableHighlight, { style: customStyle?.selectField, underlayColor: colorGrayscaleS, onPress: handleOnPressSelectField, ...touchableRestProps },
20
20
  React.createElement(View, { pointerEvents: "none" },
21
- React.createElement(InputField, { editable: false, icon: "arrow-down", label: placeholder, value: selectedValue?.label }))),
21
+ React.createElement(InputField, { editable: false, icon: "arrow-down", label: placeholder, style: customStyle?.inputField, value: selectedValue?.label }))),
22
22
  React.createElement(Modal, { visible: modalVisible, scroll: true, onClose: handleOnModalClose },
23
23
  React.createElement(View, { style: [style.modalContent, customStyle?.modalContent] }, options.map(({ label, value }) => (React.createElement(TouchableHighlight, { key: value, style: [style.option, customStyle?.option], underlayColor: colorGrayscaleS, onPress: () => handleOnPressOption(value) },
24
24
  React.createElement(Text, { level: 3, style: [style.optionText, customStyle?.optionText] }, label))))))));
@@ -1,4 +1,4 @@
1
- import { QueryStatus } from "@lookiero/messaging-react";
1
+ import { CommandStatus, QueryStatus } from "@lookiero/messaging-react";
2
2
  import React, { useCallback, useEffect, useState } from "react";
3
3
  import { View } from "react-native";
4
4
  import { useParams } from "react-router-native";
@@ -6,6 +6,7 @@ import { CheckoutItemStatus } from "../../../../domain/checkoutItem/model/checko
6
6
  import "../../../../projection/checkout/viewFirstAvailableCheckoutByCustomerId";
7
7
  import { useBookCheckouBookingForCheckoutItem } from "../../../domain/checkoutBooking/react/useBookCheckouBookingForCheckoutItem";
8
8
  import { useKeepCheckoutItem } from "../../../domain/checkoutItem/react/useKeepCheckoutItem";
9
+ import { useReturnCheckoutItem } from "../../../domain/checkoutItem/react/useReturnCheckoutItem";
9
10
  import { useViewBookedSizeChangeProductsVariantsForCheckoutItem } from "../../../projection/bookedSizeChangeProductsVariants/react/useViewBookedSizeChangeProductsVariantsForCheckoutItem";
10
11
  import { useViewFirstAvailableCheckoutByCustomerId } from "../../../projection/checkout/react/useViewFirstAvailableCheckoutByCustomerId";
11
12
  import { useListReturnQuestionsByCheckoutItemId } from "../../../projection/returnQuestion/react/useListReturnQuestionsByCheckoutItemId";
@@ -19,10 +20,20 @@ import { ProductVariantDescription } from "./components/productVariantDescriptio
19
20
  import { ProductVariantSlider } from "./components/productVariantSlider/ProductVariantSlider";
20
21
  import { ReturnQuestionsFeedback } from "./components/returnQuestionsFeedback/ReturnQuestionsFeedback";
21
22
  import { ReturnQuestionsForm } from "./components/returnQuestionsForm/ReturnQuestionsForm";
23
+ import { SizeChangeModal } from "./components/sizeChangeModal/SizeChangeModal";
24
+ import { SizeWithoutStockModal } from "./components/sizeWithoutStockModal/SizeWithoutStockModal";
22
25
  const Item = ({ customerId }) => {
23
26
  const { id } = useParams();
24
27
  const [checkout, checkoutStatus] = useViewFirstAvailableCheckoutByCustomerId({ customerId });
25
28
  const checkoutItem = checkout?.items.find((checkoutItem) => checkoutItem.id === id);
29
+ const [customerDecissionMade, setCustomerDecissionMade] = useState(() => checkoutItem.status === CheckoutItemStatus.INITIAL || checkoutItem.status === CheckoutItemStatus.EXPIRED);
30
+ const handleOnBannerPress = useCallback(() => setCustomerDecissionMade(!customerDecissionMade), [customerDecissionMade]);
31
+ const [sizeWithoutStockModalVisible, setSizeWithoutStockModalVisible] = useState(false);
32
+ const handleOnShowSizeWithoutStockModal = useCallback(() => setSizeWithoutStockModalVisible(true), []);
33
+ const handleOnHideSizeWithoutStockModal = useCallback(() => setSizeWithoutStockModalVisible(false), []);
34
+ const [sizeChangeModalVisible, setSizeChangeModalVisible] = useState(false);
35
+ const handleOnShowSizeChangeModal = useCallback(() => setSizeChangeModalVisible(true), []);
36
+ const handleOnHideSizeChangeModal = useCallback(() => setSizeChangeModalVisible(false), []);
26
37
  const [bookedSizeChangeProductsVariants, bookedSizeChangeProductsVariantsStatus] = useViewBookedSizeChangeProductsVariantsForCheckoutItem({
27
38
  checkoutItemId: checkoutItem.id,
28
39
  });
@@ -34,20 +45,25 @@ const Item = ({ customerId }) => {
34
45
  const [returnQuestions, returnQuestionsStatus] = useListReturnQuestionsByCheckoutItemId({
35
46
  checkoutItemId: checkoutItem.id,
36
47
  });
37
- const [keepCheckoutItem] = useKeepCheckoutItem({ checkoutItemId: checkoutItem.id });
48
+ const [keepCheckoutItem, keepCheckoutItemStatus] = useKeepCheckoutItem({ checkoutItemId: checkoutItem.id });
49
+ const [returnCheckoutItem, returnCheckoutItemStatus] = useReturnCheckoutItem({
50
+ checkoutItemId: checkoutItem.id,
51
+ });
52
+ const [stickyHeight, setStickyHeight] = useState(0);
53
+ const handleOnStickyLayout = useCallback(({ height }) => setStickyHeight(height), []);
38
54
  useEffect(() => {
39
55
  checkout?.bookingId === undefined && bookCheckouBooking();
40
56
  }, [bookCheckouBooking, checkout?.bookingId]);
41
- const [stickyHeight, setStickyHeight] = useState(0);
42
- const handleOnStickyLayout = useCallback(({ height }) => setStickyHeight(height), []);
43
57
  const [returnQuestionsVisible, setReturnQuestionsVisible] = useState(false);
44
58
  const handleOnShowReturnQuestions = useCallback(() => setReturnQuestionsVisible(true), []);
45
59
  const handleOnHideReturnQuestions = useCallback(() => setReturnQuestionsVisible(false), []);
46
- const handleOnEditFeedback = useCallback(() => void 0, []);
47
- const handleOnSubmit = useCallback(() => handleOnHideReturnQuestions(), [handleOnHideReturnQuestions]);
48
- const handleOnReplace = useCallback(() => void 0, []);
60
+ const handleOnEditFeedback = useCallback(() => handleOnShowReturnQuestions(), [handleOnShowReturnQuestions]);
61
+ const handleOnSubmit = useCallback((feedback) => {
62
+ handleOnHideReturnQuestions();
63
+ returnCheckoutItem({ feedbacks: feedback });
64
+ }, [handleOnHideReturnQuestions, returnCheckoutItem]);
65
+ const handleOnReplace = useCallback(() => handleOnShowSizeChangeModal(), [handleOnShowSizeChangeModal]);
49
66
  const handleOnReturn = useCallback(() => handleOnShowReturnQuestions(), [handleOnShowReturnQuestions]);
50
- const handleOnBannerPress = useCallback(() => void 0, []);
51
67
  const dependenciesLoadedStatuses = [QueryStatus.ERROR, QueryStatus.SUCCESS];
52
68
  const dependenciesLoaded = dependenciesLoadedStatuses.includes(returnQuestionsStatus) &&
53
69
  dependenciesLoadedStatuses.includes(checkoutStatus) &&
@@ -56,11 +72,12 @@ const Item = ({ customerId }) => {
56
72
  return React.createElement(Spinner, null);
57
73
  const { price } = checkoutItem;
58
74
  const { media, brand, name, size, color } = checkoutItem.productVariant;
59
- const customerDecissionMade = checkoutItem.status === CheckoutItemStatus.INITIAL || checkoutItem.status === CheckoutItemStatus.EXPIRED;
60
75
  const sizes = bookedSizeChangeProductsVariants?.productVariants
61
76
  .map((productVariant) => productVariant.size)
62
77
  .concat(checkoutItem.productVariant.size) || [];
63
78
  return (React.createElement(React.Fragment, null,
79
+ React.createElement(SizeWithoutStockModal, { visible: sizeWithoutStockModalVisible, onDismiss: handleOnHideSizeWithoutStockModal }),
80
+ React.createElement(SizeChangeModal, { visible: sizeChangeModalVisible, onDismiss: handleOnHideSizeChangeModal }),
64
81
  React.createElement(SafeAreaScrollView, null,
65
82
  React.createElement(Body, null,
66
83
  !customerDecissionMade && (React.createElement(CustomerDecissionBanner, { checkoutItemStatus: checkoutItem.status, onPress: handleOnBannerPress })),
@@ -69,8 +86,8 @@ const Item = ({ customerId }) => {
69
86
  React.createElement(ProductVariantSlider, { producVariantMedia: media })),
70
87
  React.createElement(ProductVariantDescription, { brand: brand, color: color, name: name, price: price, size: size }),
71
88
  checkoutItem.feedback && (React.createElement(View, { style: style.feedbackContainer },
72
- React.createElement(ReturnQuestionsFeedback, { feedback: checkoutItem.feedback, returnQuestions: returnQuestions || [], onEditFeedback: handleOnEditFeedback })))))),
73
- customerDecissionMade && (React.createElement(ItemActions, { size: checkoutItem.productVariant.size, sizes: sizes, onKeep: keepCheckoutItem, onLayout: handleOnStickyLayout, onReplace: handleOnReplace, onReturn: handleOnReturn })),
89
+ React.createElement(ReturnQuestionsFeedback, { feedback: checkoutItem.feedback || {}, returnQuestions: returnQuestions || [], onEditFeedback: handleOnEditFeedback })))))),
90
+ customerDecissionMade && (React.createElement(ItemActions, { keepButtonLoading: keepCheckoutItemStatus === CommandStatus.LOADING, returnButtonLoading: returnCheckoutItemStatus === CommandStatus.LOADING, size: checkoutItem.productVariant.size, sizes: sizes, onKeep: keepCheckoutItem, onLayout: handleOnStickyLayout, onReplace: handleOnReplace, onReturn: handleOnReturn, onSizeSelectorPress: handleOnShowSizeWithoutStockModal })),
74
91
  React.createElement(ReturnQuestionsForm, { checkoutItemPrice: checkoutItem.price, feedback: checkoutItem.feedback || {}, productVariant: checkoutItem.productVariant, returnQuestions: returnQuestions || [], visible: returnQuestionsVisible, onClose: handleOnHideReturnQuestions, onSubmit: handleOnSubmit })));
75
92
  };
76
93
  export { Item };
@@ -1,9 +1,10 @@
1
1
  import { FC } from "react";
2
2
  import { CheckoutItemStatus } from "../../../../../../domain/checkoutItem/model/checkoutItem";
3
- declare type Status = Exclude<CheckoutItemStatus, CheckoutItemStatus.INITIAL | CheckoutItemStatus.EXPIRED>;
3
+ declare type CustomerDecissionBannerStatus = Exclude<CheckoutItemStatus, CheckoutItemStatus.INITIAL | CheckoutItemStatus.EXPIRED>;
4
4
  interface CustomerDecissionBannerProps {
5
- readonly checkoutItemStatus: Status;
5
+ readonly checkoutItemStatus: CustomerDecissionBannerStatus;
6
6
  readonly onPress: () => void;
7
7
  }
8
8
  declare const CustomerDecissionBanner: FC<CustomerDecissionBannerProps>;
9
+ export type { CustomerDecissionBannerStatus };
9
10
  export { CustomerDecissionBanner };
@@ -4,6 +4,9 @@ import { Layout } from "../../../../shared/components/layouts/sticky/Sticky";
4
4
  interface ItemActionsProps {
5
5
  readonly sizes: SizeProjection[];
6
6
  readonly size: SizeProjection;
7
+ readonly keepButtonLoading?: boolean;
8
+ readonly returnButtonLoading?: boolean;
9
+ readonly onSizeSelectorPress?: () => void;
7
10
  readonly onKeep: (value: string) => void;
8
11
  readonly onReturn: () => void;
9
12
  readonly onReplace: () => void;
@@ -1,25 +1,31 @@
1
1
  import { Button } from "@lookiero/aurora-next/build/components/atoms/Button/Button";
2
2
  import { BUTTON_VARIANT } from "@lookiero/aurora-next/build/components/atoms/Button/Button.definition";
3
3
  import { useI18nMessage } from "@lookiero/i18n-react";
4
- import React, { useMemo } from "react";
4
+ import React, { useCallback, useMemo } from "react";
5
5
  import { View } from "react-native";
6
6
  import { Body } from "../../../../components/layouts/body/Body";
7
7
  import { I18nMessages } from "../../../../i18n/i18n";
8
8
  import { Sticky } from "../../../../shared/components/layouts/sticky/Sticky";
9
9
  import { SelectField } from "../../../../shared/components/molecules/selectField/SelectField";
10
10
  import { style } from "./ItemActions.style";
11
- const ItemActions = ({ sizes, size, onKeep, onReplace, onReturn, onLayout }) => {
11
+ const ItemActions = ({ sizes, size, keepButtonLoading = false, returnButtonLoading = false, onSizeSelectorPress = () => void 0, onKeep, onReplace, onReturn, onLayout, }) => {
12
12
  const sizeSelectorLabelText = useI18nMessage({ id: I18nMessages.ITEM_SIZES_LABEL });
13
13
  const keepButtonText = useI18nMessage({ id: I18nMessages.ITEM_KEEP_BUTTON });
14
14
  const returnButtonText = useI18nMessage({ id: I18nMessages.ITEM_RETURN_BUTTON });
15
15
  const sizeSelectorOptions = useMemo(() => sizes.map((size) => ({ label: size.lookiero, value: size.id })), [sizes]);
16
16
  const disabledSizeSelector = useMemo(() => sizeSelectorOptions.length === 1 && sizeSelectorOptions[0]?.value === size.id, [sizeSelectorOptions, size.id]);
17
+ const handleOnPressSizeSelector = useCallback(() => onSizeSelectorPress(), [onSizeSelectorPress]);
17
18
  return (React.createElement(Sticky, { onLayout: onLayout },
18
19
  React.createElement(Body, { style: { column: style.container } },
19
- React.createElement(Button, { onPress: onKeep }, keepButtonText),
20
+ React.createElement(Button, { busy: keepButtonLoading, onPress: onKeep }, keepButtonText),
20
21
  React.createElement(View, { style: style.row },
21
- !size.unique && (React.createElement(SelectField, { disabled: disabledSizeSelector, options: sizeSelectorOptions, placeholder: sizeSelectorLabelText || "", style: { selectField: style.sizeSelector }, testID: "size-selector", value: size.id, onChange: onReplace })),
22
+ !size.unique && (React.createElement(SelectField, { ...(disabledSizeSelector && {
23
+ onPress: handleOnPressSizeSelector,
24
+ }), options: sizeSelectorOptions, placeholder: sizeSelectorLabelText || "", testID: "size-selector", value: size.id, style: {
25
+ selectField: style.sizeSelector,
26
+ inputField: { input: disabledSizeSelector && style.inputDisabled },
27
+ }, onChange: onReplace })),
22
28
  React.createElement(View, { style: style.returnButtonContainer },
23
- React.createElement(Button, { variant: BUTTON_VARIANT.SECONDARY, onPress: onReturn }, returnButtonText))))));
29
+ React.createElement(Button, { busy: returnButtonLoading, variant: BUTTON_VARIANT.SECONDARY, onPress: onReturn }, returnButtonText))))));
24
30
  };
25
31
  export { ItemActions };
@@ -2,6 +2,9 @@ declare const style: {
2
2
  container: {
3
3
  paddingHorizontal: number;
4
4
  };
5
+ inputDisabled: {
6
+ color: string;
7
+ };
5
8
  returnButtonContainer: {
6
9
  flex: number;
7
10
  };
@@ -1,10 +1,13 @@
1
1
  import { StyleSheet } from "react-native";
2
2
  import { theme } from "../../../../theme/theme";
3
- const { spaceL, spaceXL } = theme();
3
+ const { colorGrayscaleL, spaceL, spaceXL } = theme();
4
4
  const style = StyleSheet.create({
5
5
  container: {
6
6
  paddingHorizontal: spaceXL,
7
7
  },
8
+ inputDisabled: {
9
+ color: colorGrayscaleL,
10
+ },
8
11
  returnButtonContainer: {
9
12
  flex: 1,
10
13
  },
@@ -8,7 +8,7 @@ interface ReturnQuestionsFormProps {
8
8
  readonly returnQuestions: ReturnQuestionProjection[];
9
9
  readonly checkoutItemPrice: PriceProjection;
10
10
  readonly productVariant: CheckoutItemProductVariantProjection;
11
- readonly onSubmit: () => void;
11
+ readonly onSubmit: (feedback: FeedbackProjection) => void;
12
12
  readonly onClose: () => void;
13
13
  }
14
14
  declare const ReturnQuestionsForm: FC<ReturnQuestionsFormProps>;
@@ -2,7 +2,7 @@ import { PortalHost } from "@gorhom/portal";
2
2
  import { Button } from "@lookiero/aurora-next/build/components/atoms/Button/Button";
3
3
  import { Text } from "@lookiero/aurora-next/build/components/primitives/Text/Text";
4
4
  import { useI18nMessage } from "@lookiero/i18n-react";
5
- import React from "react";
5
+ import React, { useCallback } from "react";
6
6
  import { View } from "react-native";
7
7
  import { ReturnQuestionType, } from "../../../../../../projection/returnQuestion/returnQuestion";
8
8
  import { ReturnQuestions } from "../../../../components/organisms/returnQuestions/ReturnQuestions";
@@ -33,10 +33,11 @@ const ReturnQuestionsForm = ({ feedback, returnQuestions, checkoutItemPrice, pro
33
33
  prefix: RETURN_QUESTIONS_PREFIX,
34
34
  });
35
35
  const { media, brand, name, size, color } = productVariant;
36
+ const handleOnSubmit = useCallback(() => onSubmit(feedback), [feedback, onSubmit]);
36
37
  return (React.createElement(ReturnQuestionFeedbackProvider, { feedback: feedback },
37
38
  React.createElement(ReturnQuestionItemProvider, { returnQuestionItems: returnQuestionItems },
38
39
  React.createElement(PortalHost, { name: RETURN_QUESTION_FORM_PORTAL_HOST_NAME }),
39
- React.createElement(Modal, { footer: React.createElement(Button, { onPress: onSubmit }, submitButtonText), portalHostName: RETURN_QUESTION_FORM_PORTAL_HOST_NAME, visible: visible, scroll: true, showCloseButton: true, onClose: onClose },
40
+ React.createElement(Modal, { footer: React.createElement(Button, { onPress: handleOnSubmit }, submitButtonText), portalHostName: RETURN_QUESTION_FORM_PORTAL_HOST_NAME, visible: visible, scroll: true, showCloseButton: true, onClose: onClose },
40
41
  React.createElement(View, { style: style.returnQuestionsContainer },
41
42
  React.createElement(Text, { level: 2, style: style.title }, titleText),
42
43
  React.createElement(ProductVariant, { brand: brand, color: color, media: media, name: name, price: checkoutItemPrice, size: size }),
@@ -1,16 +1,13 @@
1
1
  import { Text } from "@lookiero/aurora-next/build/components/primitives/Text/Text";
2
2
  import { useI18nMessage } from "@lookiero/i18n-react";
3
- import React, { useState } from "react";
3
+ import React from "react";
4
4
  import { StyleSheet, View } from "react-native";
5
5
  import { SafeAreaScrollView } from "../../components/templates/SafeAreaScrollView";
6
- import { SizeWithoutStockModal } from "../item/components/sizeWithoutStockModal/SizeWithoutStockModal";
7
6
  const Summary = () => {
8
7
  const summaryText = useI18nMessage({ id: "summary" });
9
- const [modalVisible, setModalVisible] = useState(true);
10
8
  return (React.createElement(SafeAreaScrollView, null,
11
9
  React.createElement(View, { style: styles.container },
12
- React.createElement(Text, { heading: true, level: 3 }, summaryText),
13
- React.createElement(SizeWithoutStockModal, { visible: modalVisible, onDismiss: () => setModalVisible(false) }))));
10
+ React.createElement(Text, { heading: true, level: 3 }, summaryText))));
14
11
  };
15
12
  const styles = StyleSheet.create({
16
13
  container: {
@@ -47,7 +47,7 @@ interface CheckoutItemProjection {
47
47
  readonly price: PriceProjection;
48
48
  readonly replacedFor?: string;
49
49
  readonly productVariant: CheckoutItemProductVariantProjection;
50
- readonly feedback: FeedbackProjection | null;
50
+ readonly feedback: FeedbackProjection;
51
51
  }
52
52
  export type { CheckoutItemProjection, CheckoutItemProductVariantProjection, ColorProjection, MediaProjection, PriceProjection, };
53
53
  export { Currency, MediaPerspective };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lookiero/checkout",
3
- "version": "0.2.40",
3
+ "version": "0.2.42",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [