133 lines
3.6 KiB
TypeScript
133 lines
3.6 KiB
TypeScript
import { View, Text, GestureResponderEvent } from "react-native";
|
|
import { IconButton } from "react-native-paper";
|
|
|
|
import { useAppSelector } from "@/store/hooks";
|
|
import { selectIsMobile } from "@/store/screen/screenSizeSlice";
|
|
|
|
interface TablePaginationProps {
|
|
page: number;
|
|
itemsPerPage: number;
|
|
totalItems: number;
|
|
from: number;
|
|
to: number;
|
|
onPageChange: (page: number) => void;
|
|
onItemsPerPageButtonPress: (event: GestureResponderEvent) => void;
|
|
}
|
|
|
|
export const TablePagination = ({
|
|
page,
|
|
itemsPerPage,
|
|
totalItems,
|
|
from,
|
|
to,
|
|
onPageChange,
|
|
onItemsPerPageButtonPress,
|
|
}: TablePaginationProps) => {
|
|
const isMobile = useAppSelector(selectIsMobile);
|
|
const maxPage = Math.ceil(totalItems / itemsPerPage) - 1;
|
|
|
|
const desktopNavigationButtons = (
|
|
<>
|
|
<Text className="text-sm mr-2">{`${from}-${to} of ${totalItems}`}</Text>
|
|
<IconButton
|
|
icon="chevron-double-left"
|
|
size={20}
|
|
disabled={page === 0}
|
|
onPress={() => onPageChange(0)}
|
|
/>
|
|
<IconButton
|
|
icon="chevron-left"
|
|
size={20}
|
|
disabled={page === 0}
|
|
onPress={() => onPageChange(Math.max(0, page - 1))}
|
|
/>
|
|
<IconButton
|
|
icon="chevron-right"
|
|
size={20}
|
|
disabled={page >= maxPage}
|
|
onPress={() => onPageChange(Math.min(maxPage, page + 1))}
|
|
/>
|
|
<IconButton
|
|
icon="chevron-double-right"
|
|
size={20}
|
|
disabled={page >= maxPage}
|
|
onPress={() => onPageChange(maxPage)}
|
|
/>
|
|
</>
|
|
);
|
|
|
|
const mobileNavigationButtons = (
|
|
<>
|
|
<IconButton
|
|
icon="chevron-double-left"
|
|
size={16}
|
|
style={{ margin: 0 }}
|
|
disabled={page === 0}
|
|
onPress={() => onPageChange(0)}
|
|
/>
|
|
<IconButton
|
|
icon="chevron-left"
|
|
size={16}
|
|
style={{ margin: 0 }}
|
|
disabled={page === 0}
|
|
onPress={() => onPageChange(Math.max(0, page - 1))}
|
|
/>
|
|
<IconButton
|
|
icon="chevron-right"
|
|
size={16}
|
|
style={{ margin: 0 }}
|
|
disabled={page >= maxPage}
|
|
onPress={() => onPageChange(Math.min(maxPage, page + 1))}
|
|
/>
|
|
<IconButton
|
|
icon="chevron-double-right"
|
|
size={16}
|
|
style={{ margin: 0 }}
|
|
disabled={page >= maxPage}
|
|
onPress={() => onPageChange(maxPage)}
|
|
/>
|
|
</>
|
|
);
|
|
|
|
const itemsPerPageControls = (
|
|
<>
|
|
<IconButton icon="menu" size={20} onPress={onItemsPerPageButtonPress} />
|
|
<Text className="text-sm">{`${itemsPerPage} per page`}</Text>
|
|
</>
|
|
);
|
|
|
|
return (
|
|
<View
|
|
className="mt-4 flex items-center"
|
|
style={{
|
|
marginLeft: isMobile ? 0 : "auto",
|
|
width: isMobile ? "100%" : "auto",
|
|
}}
|
|
>
|
|
{isMobile ? (
|
|
<View className="bg-white py-1 px-2 rounded-md w-full">
|
|
<View className="flex-row items-center justify-between">
|
|
<View className="flex-row items-center">{mobileNavigationButtons}</View>
|
|
<Text className="text-xs text-gray-600">{`${from}-${to} / ${totalItems}`}</Text>
|
|
<View className="flex-row items-center">
|
|
<IconButton
|
|
icon="menu"
|
|
size={16}
|
|
style={{ margin: 0 }}
|
|
onPress={onItemsPerPageButtonPress}
|
|
/>
|
|
<Text className="text-xs text-gray-600">{`${itemsPerPage}/page`}</Text>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
) : (
|
|
<View className="flex-row items-center bg-white py-0.5 px-3 rounded-md">
|
|
{desktopNavigationButtons}
|
|
<View className="h-4 w-px bg-gray-300 mx-2" />
|
|
{itemsPerPageControls}
|
|
</View>
|
|
)}
|
|
</View>
|
|
);
|
|
};
|