All files / apps/host/src/components/RequestList index.tsx

100% Statements 19/19
78.57% Branches 22/28
100% Functions 9/9
100% Lines 18/18

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109                                          4x 9x     9x                     9x         9x   9x 2x 5x       9x 2x     9x 1x     1x               9x   9x                   12x   12x                                     4x                    
import React, { memo, useCallback, useMemo } from 'react';
import { StyleSheet, Text, View } from 'react-native';
 
import { FlashList } from '@shopify/flash-list';
import { useQueryClient } from '@tanstack/react-query';
 
import RequestCard from '@/components/RequestCard';
import { RequestSkeleton } from '@/components/RequestListSkeleton';
 
import { useGetMyRequests, useGetRequests } from '@/hooks/useRequest';
 
import { QUERY_KEYS } from '@/constants/apis';
 
import { RequestCategory, RequestStatus } from '@/types/request';
 
interface Props {
  status?: RequestStatus;
  isMyRequest?: boolean;
  onPressItem: (id: string, category: RequestCategory) => void;
}
 
const RequestList = ({ status, isMyRequest = false, onPressItem }: Props) => {
  const queryClient = useQueryClient();
 
  const { data, isLoading, error, fetchNextPage, isRefetching, isFetchingNextPage } =
    useGetRequests({
      status,
      disabled: isMyRequest,
    });
 
  const {
    data: myRequestData,
    isLoading: isMyRequestLoading,
    error: myRequestError,
    fetchNextPage: myRequestFetchNextPage,
    isRefetching: myRequestIsReFetching,
  } = useGetMyRequests({
    status,
    disabled: !isMyRequest,
  });
 
  const requests = useMemo(
    () =>
      (isMyRequest
        ? myRequestData?.pages.flatMap(page => page.data.items)
        : data?.pages.flatMap(page => page.data.items)) ?? [],
    [data, myRequestData, isMyRequest],
  );
 
  const handleLoadMore = useCallback(() => {
    isMyRequest ? myRequestFetchNextPage() : fetchNextPage();
  }, [fetchNextPage, isMyRequest, myRequestFetchNextPage]);
 
  const handleRefresh = useCallback(() => {
    queryClient.refetchQueries({
      queryKey: [isMyRequest ? QUERY_KEYS.MY_REQUESTS : QUERY_KEYS.LIST_REQUESTS],
    });
    status &&
      queryClient.refetchQueries({
        queryKey: isMyRequest
          ? [QUERY_KEYS.MY_REQUESTS, status]
          : [QUERY_KEYS.LIST_REQUESTS, status],
      });
  }, [isMyRequest, queryClient, status]);
 
  const isLoadingData = isLoading || isRefetching || isMyRequestLoading || myRequestIsReFetching;
 
  return (
    <View style={styles.container}>
      {error && <Text>{error.message}</Text>}
      {myRequestError && <Text>{myRequestError.message}</Text>}
      {isLoadingData ? (
        <RequestSkeleton />
      ) : (
        <FlashList
          onRefresh={handleRefresh}
          data={requests}
          keyExtractor={item => item.id}
          renderItem={({ item }) => (
            <RequestCard {...item} onPress={() => onPressItem(item.id, item.category)} />
          )}
          showsVerticalScrollIndicator={false}
          contentContainerStyle={styles.contentContainer}
          onEndReached={handleLoadMore}
          onEndReachedThreshold={0.5}
          {...(isFetchingNextPage && {
            ListFooterComponent: <RequestSkeleton />,
          })}
          {...(requests.length === 0 &&
            !isLoadingData && {
              ListEmptyComponent: <Text className="text-center text-xl">No request found</Text>,
            })}
        />
      )}
    </View>
  );
};
 
const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  contentContainer: {
    paddingBottom: 20,
  },
});
 
export default memo(RequestList);