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

100% Statements 19/19
78.57% Branches 22/28
100% Functions 8/8
100% Lines 19/19

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 110 111 112 113 114                                          4x 9x     9x                     9x         9x   9x 2x 5x       9x 2x     9x 1x     1x               9x   9x 12x       9x                   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;
 
  const renderItem = useCallback(
    ({ item }: { item: any }) => <RequestCard {...item} onPress={onPressItem} />,
    [onPressItem],
  );
 
  return (
    <View style={styles.container}>
      {error && <Text accessibilityRole="alert">{error.message}</Text>}
      {myRequestError && <Text accessibilityRole="alert">{myRequestError.message}</Text>}
      {isLoadingData ? (
        <RequestSkeleton />
      ) : (
        <FlashList
          onRefresh={handleRefresh}
          data={requests}
          keyExtractor={item => item.id}
          renderItem={renderItem}
          showsVerticalScrollIndicator={false}
          contentContainerStyle={styles.contentContainer}
          onEndReached={handleLoadMore}
          onEndReachedThreshold={0.5}
          accessibilityRole="list"
          accessibilityLabel="Requests"
          {...(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);