87 lines
2.3 KiB
TypeScript
87 lines
2.3 KiB
TypeScript
import { Pagination } from "@/api/types";
|
|
import { ReactElement, RefObject } from "react";
|
|
import { ScrollView, View } from "react-native";
|
|
import { Button, ButtonText } from "../button";
|
|
import { ThemedText } from "../themed-text";
|
|
|
|
type CustomFlatListProps<T> = {
|
|
pagination?: Pagination<T>;
|
|
skeleton: ReactElement;
|
|
skeletonStartCount?: number;
|
|
currentPage: number;
|
|
setCurrentPage: (v: number) => void;
|
|
isLoadingPage: boolean;
|
|
renderItem: (item: T) => ReactElement;
|
|
pagesRadius?: number;
|
|
dividerHeight?: number;
|
|
scrollView?: RefObject<ScrollView | null>;
|
|
};
|
|
|
|
const PaginationList = <T,>({
|
|
pagination,
|
|
skeleton,
|
|
currentPage,
|
|
setCurrentPage,
|
|
isLoadingPage,
|
|
renderItem,
|
|
scrollView,
|
|
pagesRadius = 3,
|
|
skeletonStartCount = 4,
|
|
dividerHeight = 16,
|
|
}: CustomFlatListProps<T>) => {
|
|
const renderSkeleton = () => {
|
|
const skeletonCount = pagination
|
|
? pagination.meta.per_page
|
|
: skeletonStartCount;
|
|
return Array.from({ length: skeletonCount }).map((_, i) => (
|
|
<View key={i} style={{ marginBottom: dividerHeight }}>
|
|
{skeleton}
|
|
</View>
|
|
));
|
|
};
|
|
const handlePagePress = (page: number) => {
|
|
if (page === currentPage) return;
|
|
setCurrentPage(page);
|
|
scrollView?.current?.scrollTo({ y: 0, animated: false });
|
|
};
|
|
|
|
if (!pagination || isLoadingPage) return renderSkeleton();
|
|
|
|
return (
|
|
<View>
|
|
{pagination.data.map((item, index) => (
|
|
<View key={index}>
|
|
{renderItem(item)}
|
|
<View style={{ height: dividerHeight }} />
|
|
</View>
|
|
))}
|
|
{pagination.data.length === 0 && (
|
|
<ThemedText className="pt-4 text-center">No items found.</ThemedText>
|
|
)}
|
|
<View className="flex-row gap-3">
|
|
{currentPage > 1 && (
|
|
<Button
|
|
className="flex-1"
|
|
onPress={() => handlePagePress(currentPage - 1)}
|
|
action="secondary"
|
|
>
|
|
<ButtonText>Prev</ButtonText>
|
|
</Button>
|
|
)}
|
|
|
|
{currentPage !== pagination.meta.last_page && (
|
|
<Button
|
|
className="flex-1"
|
|
onPress={() => handlePagePress(currentPage + 1)}
|
|
action="secondary"
|
|
>
|
|
<ButtonText>Next</ButtonText>
|
|
</Button>
|
|
)}
|
|
</View>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
export default PaginationList;
|