Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: [PE-725] CGN merchant categories list details transition header #6313

Merged
merged 11 commits into from
Oct 23, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,22 @@ import { Divider, IOVisualCostants } from "@pagopa/io-app-design-system";
import { View } from "react-native";
import Placeholder from "rn-placeholder";

export function CgnMerchantListSkeleton() {
type Props = {
hasIcons?: boolean;
};

export function CgnMerchantListSkeleton(props: Props) {
const { hasIcons = false } = props;

return (
<View>
<View testID="CgnMerchantListSkeleton">
{new Array(6).fill(null).map((_, index) => (
<View key={index}>
<View key={index} testID={`CgnMerchantListSkeleton-Item-${index}`}>
<View
style={{
paddingHorizontal: IOVisualCostants.appMarginDefault
paddingHorizontal: hasIcons
? 0
: IOVisualCostants.appMarginDefault
}}
>
<Placeholder.Box
Expand All @@ -21,6 +29,7 @@ export function CgnMerchantListSkeleton() {
style={{
marginVertical: 13
}}
testID={`CgnMerchantListSkeleton-Placeholder-${index}`}
/>
</View>
<Divider />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import * as pot from "@pagopa/ts-commons/lib/pot";
import {
Badge,
Body,
Expand All @@ -9,30 +8,32 @@ import {
ListItemAction,
ListItemNav
} from "@pagopa/io-app-design-system";
import * as React from "react";
import { FlatList, RefreshControl, View } from "react-native";
import * as pot from "@pagopa/ts-commons/lib/pot";
import { useNavigation } from "@react-navigation/native";
import { pipe } from "fp-ts/lib/function";
import * as O from "fp-ts/lib/Option";
import { useNavigation } from "@react-navigation/native";
import * as React from "react";
import { FlatList, RefreshControl, View } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { ProductCategoryWithNewDiscountsCount } from "../../../../../../definitions/cgn/merchants/ProductCategoryWithNewDiscountsCount";
import { getCategorySpecs } from "../../utils/filters";
import I18n from "../../../../../i18n";
import { IOStackNavigationProp } from "../../../../../navigation/params/AppParamsList";
import { CgnDetailsParamsList } from "../../navigation/params";
import { useIODispatch, useIOSelector } from "../../../../../store/hooks";
import { cgnCategoriesListSelector } from "../../store/reducers/categories";
import { cgnCategories } from "../../store/actions/categories";
import CGN_ROUTES from "../../navigation/routes";
import { useIOBottomSheetAutoresizableModal } from "../../../../../utils/hooks/bottomSheet";
import { isDesignSystemEnabledSelector } from "../../../../../store/reducers/persistedPreferences";
import { useIOBottomSheetAutoresizableModal } from "../../../../../utils/hooks/bottomSheet";
import { CgnDetailsParamsList } from "../../navigation/params";
import CGN_ROUTES from "../../navigation/routes";
import { cgnCategories } from "../../store/actions/categories";
import { cgnCategoriesListSelector } from "../../store/reducers/categories";
import { getCategorySpecs } from "../../utils/filters";
import { CgnMerchantListSkeleton } from "../../components/merchants/CgnMerchantListSkeleton";

export const CgnMerchantCategoriesListScreen = () => {
const insets = useSafeAreaInsets();
const isFirstRender = React.useRef<boolean>(true);
const dispatch = useIODispatch();
const [isRefreshing, setIsRefreshing] = React.useState(false);
const [isPullRefresh, setIsPullRefresh] = React.useState(false);
const potCategories = useIOSelector(cgnCategoriesListSelector);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need two separate states to track this behavior? I believe we could manage with just one state that tracks the pull-to-refresh behavior. When the user opens this screen for the first time, the skeletons should always be shown as long as the pot is in a noneLoading state (i.e., both pot.isNone and pot.isLoading). About the the pull-to-refresh, having a separate state makes sense, but for the initial load, a single state should be enough if you check if the pot is none but in loading. What do you think?


const isDesignSystemEnabled = useIOSelector(isDesignSystemEnabledSelector);

const navigation =
Expand All @@ -53,8 +54,15 @@ export const CgnMerchantCategoriesListScreen = () => {
});

const loadCategories = () => {
setIsRefreshing(true);
dispatch(cgnCategories.request());
};

const onPullRefresh = () => {
setIsPullRefresh(true);
dispatch(cgnCategories.request());
};

React.useEffect(loadCategories, [dispatch]);

const isError = React.useMemo(
Expand All @@ -63,13 +71,18 @@ export const CgnMerchantCategoriesListScreen = () => {
);

React.useEffect(() => {
Hantex9 marked this conversation as resolved.
Show resolved Hide resolved
if (!isFirstRender.current && isError) {
if (isError) {
IOToast.error(I18n.t("global.genericError"));
}
// eslint-disable-next-line functional/immutable-data
isFirstRender.current = false;
}, [isError]);

React.useEffect(() => {
if (pot.isSome(potCategories) && !pot.isLoading(potCategories)) {
setIsRefreshing(false);
setIsPullRefresh(false);
}
}, [potCategories]);

const renderCategoryElement = (
category: ProductCategoryWithNewDiscountsCount,
i: number
Expand Down Expand Up @@ -120,7 +133,8 @@ export const CgnMerchantCategoriesListScreen = () => {
<>
{bottomSheet}
<FlatList
data={categoriesToArray}
ListEmptyComponent={() => <CgnMerchantListSkeleton hasIcons />}
data={isRefreshing ? [] : categoriesToArray}
style={[
IOStyles.horizontalContentPadding,
IOStyles.flex,
Expand All @@ -130,8 +144,8 @@ export const CgnMerchantCategoriesListScreen = () => {
renderItem={({ item, index }) => renderCategoryElement(item, index)}
refreshControl={
<RefreshControl
refreshing={pot.isLoading(potCategories)}
onRefresh={loadCategories}
refreshing={isPullRefresh}
onRefresh={onPullRefresh}
/>
}
ItemSeparatorComponent={() => <Divider />}
Expand Down
Loading