2026-01-05 20:36:43 +01:00

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;