@lookiero/checkout 0.2.45 → 0.2.47

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.
@@ -0,0 +1,26 @@
1
+ import { FC, ReactNode } from "react";
2
+ import { StyleProp, TextStyle, ViewStyle } from "react-native";
3
+ interface TabStyle {
4
+ readonly tab: StyleProp<ViewStyle>;
5
+ readonly tabText: StyleProp<TextStyle>;
6
+ }
7
+ interface TabListStyle {
8
+ readonly tabList: StyleProp<ViewStyle>;
9
+ readonly indicator: StyleProp<ViewStyle>;
10
+ readonly tab: Partial<TabStyle>;
11
+ }
12
+ interface TabsStyle {
13
+ readonly tabContainer: StyleProp<ViewStyle>;
14
+ readonly sliderContainer: StyleProp<ViewStyle>;
15
+ readonly tabList: Partial<TabListStyle>;
16
+ }
17
+ interface TabsProps {
18
+ readonly children: JSX.Element[];
19
+ readonly defaultIndex?: number;
20
+ readonly tabLabels: string[];
21
+ readonly style?: Partial<TabsStyle>;
22
+ readonly onChanged?: (index: number) => void;
23
+ readonly tabLabelsWrapper?: (children: ReactNode) => ReactNode;
24
+ }
25
+ declare const Tabs: FC<TabsProps>;
26
+ export { Tabs };
@@ -0,0 +1,47 @@
1
+ import { Text } from "@lookiero/aurora-next/build/components/primitives/Text/Text";
2
+ import { animated, useSpring } from "@react-spring/native";
3
+ import React, { Children, useCallback, useState } from "react";
4
+ import { Pressable, View } from "react-native";
5
+ import invariant from "tiny-invariant";
6
+ import { Slider } from "../../../shared/components/layouts/slider/Slider";
7
+ import { style } from "./Tabs.style";
8
+ const Tab = ({ children, active, disabled = false, style: customStyle, onPress, onLayout }) => (React.createElement(Pressable, { disabled: disabled, style: [style.tab, customStyle?.tab], testID: "tab", onLayout: onLayout, onPress: onPress },
9
+ React.createElement(Text, { level: 2, style: [style.tabText, active && style.tabActiveText, customStyle?.tabText], detail: true }, children)));
10
+ const TabList = ({ labels = [], tabIndex = 0, style: customStyle, onSelect }) => {
11
+ const [tabItemPositions, setTabItemPositions] = useState([]);
12
+ const handleOnLayout = useCallback(({ nativeEvent: { layout: { width, x }, }, }, index) => setTabItemPositions((prevState) => [
13
+ ...prevState.slice(0, index),
14
+ {
15
+ position: x,
16
+ width,
17
+ },
18
+ ...prevState.slice(index),
19
+ ]), []);
20
+ const springs = useSpring({
21
+ width: tabItemPositions[tabIndex]?.width,
22
+ left: tabItemPositions[tabIndex]?.position,
23
+ });
24
+ return (React.createElement(View, { style: [style.tabs, customStyle?.tabList], testID: "tab-list" },
25
+ labels.map((item, index) => (React.createElement(Tab, { key: index, active: tabIndex === index, style: customStyle?.tab, onLayout: (event) => handleOnLayout(event, index), onPress: () => onSelect?.(index) }, item))),
26
+ React.createElement(animated.View, { style: [
27
+ style.indicator,
28
+ {
29
+ width: springs.width,
30
+ left: springs.left,
31
+ },
32
+ customStyle?.indicator,
33
+ ] })));
34
+ };
35
+ const Tabs = ({ children, defaultIndex = 0, tabLabels, style: customStyle, onChanged, tabLabelsWrapper = (children) => children, }) => {
36
+ invariant(Children.count(children) === tabLabels.length, "Children and tab labels must be the same length");
37
+ const [active, setActive] = useState(defaultIndex);
38
+ const handleOnActiveChanged = useCallback((activeIndex) => {
39
+ setActive(activeIndex);
40
+ onChanged?.(activeIndex);
41
+ }, [onChanged]);
42
+ return (React.createElement(View, { style: [style.container, customStyle?.tabContainer], testID: "tabs" },
43
+ tabLabelsWrapper(React.createElement(TabList, { labels: tabLabels, style: customStyle?.tabList, tabIndex: active, onSelect: handleOnActiveChanged })),
44
+ React.createElement(View, { style: customStyle?.sliderContainer },
45
+ React.createElement(Slider, { active: active, gesturesEnabled: false, paginationEnabled: false, onChanged: handleOnActiveChanged }, children))));
46
+ };
47
+ export { Tabs };
@@ -0,0 +1,32 @@
1
+ declare const style: {
2
+ container: {
3
+ width: string;
4
+ };
5
+ indicator: {
6
+ backgroundColor: string;
7
+ bottom: number;
8
+ display: "flex";
9
+ height: number;
10
+ position: "absolute";
11
+ };
12
+ tab: {
13
+ marginHorizontal: number;
14
+ paddingVertical: number;
15
+ };
16
+ tabActiveText: {
17
+ color: string;
18
+ };
19
+ tabText: {
20
+ color: string;
21
+ };
22
+ tabs: {
23
+ alignItems: "center";
24
+ backgroundColor: string;
25
+ borderBottomColor: string;
26
+ borderBottomWidth: number;
27
+ flexDirection: "row";
28
+ justifyContent: "center";
29
+ marginBottom: number;
30
+ };
31
+ };
32
+ export { style };
@@ -0,0 +1,35 @@
1
+ import { StyleSheet } from "react-native";
2
+ import { theme } from "../../../theme/theme";
3
+ const { colorBase, colorContent, colorGrayscaleS, colorGrayscaleL, spaceM, spaceXL } = theme();
4
+ const style = StyleSheet.create({
5
+ container: {
6
+ width: "100%",
7
+ },
8
+ indicator: {
9
+ backgroundColor: colorContent,
10
+ bottom: -1,
11
+ display: "flex",
12
+ height: 1,
13
+ position: "absolute",
14
+ },
15
+ tab: {
16
+ marginHorizontal: spaceM,
17
+ paddingVertical: spaceM,
18
+ },
19
+ tabActiveText: {
20
+ color: colorContent,
21
+ },
22
+ tabText: {
23
+ color: colorGrayscaleL,
24
+ },
25
+ tabs: {
26
+ alignItems: "center",
27
+ backgroundColor: colorBase,
28
+ borderBottomColor: colorGrayscaleS,
29
+ borderBottomWidth: 1,
30
+ flexDirection: "row",
31
+ justifyContent: "center",
32
+ marginBottom: spaceXL,
33
+ },
34
+ });
35
+ export { style };
@@ -32,6 +32,8 @@ declare enum I18nMessages {
32
32
  FEEDBACK_TITLE = "feedback.title",
33
33
  FEEDBACK_UNANSWERED = "feedback.unanswered",
34
34
  RETURN_QUESTIONS_TITLE = "return_questions.title",
35
- RETURN_QUESTIONS_SUBMIT_BUTTON = "return_questions.submit_button"
35
+ RETURN_QUESTIONS_SUBMIT_BUTTON = "return_questions.submit_button",
36
+ SUMMARY_KEEP_TAB = "summary.keep_tab",
37
+ SUMMARY_RETURN_TAB = "summary.return_tab"
36
38
  }
37
39
  export { I18nMessages, COLOR_I18N_PREFIX, RETURN_QUESTIONS_PREFIX, RETURN_QUESTIONS_FEEDBACK_PREFIX };
@@ -34,5 +34,7 @@ var I18nMessages;
34
34
  I18nMessages["FEEDBACK_UNANSWERED"] = "feedback.unanswered";
35
35
  I18nMessages["RETURN_QUESTIONS_TITLE"] = "return_questions.title";
36
36
  I18nMessages["RETURN_QUESTIONS_SUBMIT_BUTTON"] = "return_questions.submit_button";
37
+ I18nMessages["SUMMARY_KEEP_TAB"] = "summary.keep_tab";
38
+ I18nMessages["SUMMARY_RETURN_TAB"] = "summary.return_tab";
37
39
  })(I18nMessages || (I18nMessages = {}));
38
40
  export { I18nMessages, COLOR_I18N_PREFIX, RETURN_QUESTIONS_PREFIX, RETURN_QUESTIONS_FEEDBACK_PREFIX };
@@ -40,7 +40,7 @@ const Routing = ({ onNotAccessible, customerId, locale, I18n, onI18nError }) =>
40
40
  {
41
41
  path: Routes.SUMMARY,
42
42
  element: (React.createElement(Suspense, { fallback: React.createElement(Spinner, null) },
43
- React.createElement(Summary, null))),
43
+ React.createElement(Summary, { customerId: customerId }))),
44
44
  },
45
45
  ],
46
46
  },
@@ -1,3 +1,6 @@
1
1
  import { FC } from "react";
2
- declare const Summary: FC;
2
+ interface SummaryProps {
3
+ readonly customerId: string;
4
+ }
5
+ declare const Summary: FC<SummaryProps>;
3
6
  export { Summary };
@@ -1,19 +1,18 @@
1
- import { Text } from "@lookiero/aurora-next/build/components/primitives/Text/Text";
2
- import { useI18nMessage } from "@lookiero/i18n-react";
1
+ import { QueryStatus } from "@lookiero/messaging-react";
3
2
  import React from "react";
4
- import { StyleSheet, View } from "react-native";
3
+ import { useViewFirstAvailableCheckoutByCustomerId } from "../../../projection/checkout/react/useViewFirstAvailableCheckoutByCustomerId";
4
+ import { Body } from "../../components/layouts/body/Body";
5
5
  import { SafeAreaScrollView } from "../../components/templates/SafeAreaScrollView";
6
- const Summary = () => {
7
- const summaryText = useI18nMessage({ id: "summary" });
6
+ import { Spinner } from "../../shared/components/atoms/spinner/Spinner";
7
+ import { CheckoutItemsTabs } from "./components/checkoutItemsTabs/CheckoutItemsTabs";
8
+ const Summary = ({ customerId }) => {
9
+ const [checkout, checkoutStatus] = useViewFirstAvailableCheckoutByCustomerId({ customerId });
10
+ const dependenciesLoadedStatuses = [QueryStatus.ERROR, QueryStatus.SUCCESS];
11
+ const dependenciesLoaded = dependenciesLoadedStatuses.includes(checkoutStatus);
12
+ if (!dependenciesLoaded)
13
+ return React.createElement(Spinner, null);
8
14
  return (React.createElement(SafeAreaScrollView, null,
9
- React.createElement(View, { style: styles.container },
10
- React.createElement(Text, { heading: true, level: 3 }, summaryText))));
15
+ React.createElement(Body, null,
16
+ React.createElement(CheckoutItemsTabs, { checkoutItems: checkout?.items || [] }))));
11
17
  };
12
- const styles = StyleSheet.create({
13
- container: {
14
- alignItems: "center",
15
- flex: 1,
16
- justifyContent: "center",
17
- },
18
- });
19
18
  export { Summary };
@@ -0,0 +1,7 @@
1
+ import { FC } from "react";
2
+ import { CheckoutItemProjection } from "../../../../../../projection/checkoutItem/checkoutItem";
3
+ interface CheckoutItemsTabsProps {
4
+ readonly checkoutItems: CheckoutItemProjection[];
5
+ }
6
+ declare const CheckoutItemsTabs: FC<CheckoutItemsTabsProps>;
7
+ export { CheckoutItemsTabs };
@@ -0,0 +1,20 @@
1
+ import { useI18nMessage } from "@lookiero/i18n-react";
2
+ import React, { useMemo } from "react";
3
+ import { View } from "react-native";
4
+ import { CheckoutItemStatus } from "../../../../../../domain/checkoutItem/model/checkoutItem";
5
+ import { Tabs } from "../../../../components/layouts/tabs/Tabs";
6
+ import { I18nMessages } from "../../../../i18n/i18n";
7
+ import { ProductVariant } from "../../../item/components/productVariant/ProductVariant";
8
+ import { style } from "./CheckoutItemsTabs.style";
9
+ const CheckoutItem = ({ checkoutItem, testID }) => (React.createElement(View, { style: style.checkoutItem, testID: testID },
10
+ React.createElement(ProductVariant, { brand: checkoutItem.productVariant.brand, color: checkoutItem.productVariant.color, media: checkoutItem.productVariant.media, name: checkoutItem.productVariant.name, price: checkoutItem.price, size: checkoutItem.productVariant.size })));
11
+ const CheckoutItemsTabs = ({ checkoutItems }) => {
12
+ const keepTabText = useI18nMessage({ id: I18nMessages.SUMMARY_KEEP_TAB });
13
+ const returnTabText = useI18nMessage({ id: I18nMessages.SUMMARY_RETURN_TAB });
14
+ const keepCheckoutItems = useMemo(() => checkoutItems.filter((checkoutItem) => checkoutItem.status === CheckoutItemStatus.KEPT || checkoutItem.status === CheckoutItemStatus.REPLACED), [checkoutItems]);
15
+ const returnCheckoutItems = useMemo(() => checkoutItems.filter((checkoutItem) => checkoutItem.status === CheckoutItemStatus.RETURNED || checkoutItem.status === CheckoutItemStatus.REPLACED), [checkoutItems]);
16
+ return (React.createElement(Tabs, { style: { sliderContainer: style.sliderContainer }, tabLabels: [`${keepTabText} (${keepCheckoutItems.length})`, `${returnTabText} (${returnCheckoutItems.length})`] },
17
+ React.createElement(React.Fragment, null, keepCheckoutItems.map((checkoutItem) => (React.createElement(CheckoutItem, { key: checkoutItem.id, checkoutItem: checkoutItem, testID: "keep-checkout-item" })))),
18
+ React.createElement(React.Fragment, null, returnCheckoutItems.map((checkoutItem) => (React.createElement(CheckoutItem, { key: checkoutItem.id, checkoutItem: checkoutItem, testID: "return-checkout-item" }))))));
19
+ };
20
+ export { CheckoutItemsTabs };
@@ -0,0 +1,9 @@
1
+ declare const style: {
2
+ checkoutItem: {
3
+ paddingVertical: number;
4
+ };
5
+ sliderContainer: {
6
+ paddingHorizontal: number;
7
+ };
8
+ };
9
+ export { style };
@@ -0,0 +1,12 @@
1
+ import { StyleSheet } from "react-native";
2
+ import { theme } from "../../../../theme/theme";
3
+ const { spaceM, spaceXL } = theme();
4
+ const style = StyleSheet.create({
5
+ checkoutItem: {
6
+ paddingVertical: spaceM,
7
+ },
8
+ sliderContainer: {
9
+ paddingHorizontal: spaceXL,
10
+ },
11
+ });
12
+ export { style };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lookiero/checkout",
3
- "version": "0.2.45",
3
+ "version": "0.2.47",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [