PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.5
Yatra – Travel Booking & Tour Operator Software v3.0.5
3.0.16 3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 All 84 releases
yatra / resources / js / components / shared / Pagination.tsx

Pagination.tsx in Yatra – Travel Booking & Tour Operator Software 3.0.5, at resources/js/components/shared/Pagination.tsx

142 lines 3.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import React from "react";
2 import { Button } from "../ui/button";
3 import { __ } from "../../lib/i18n";
4
5 interface PaginationProps {
6 currentPage: number;
7 totalPages: number;
8 totalItems: number;
9 itemsPerPage: number;
10 onPageChange: (page: number) => void;
11 itemName?: string; // e.g., 'activities', 'destinations'
12 }
13
14 export const Pagination: React.FC<PaginationProps> = ({
15 currentPage,
16 totalPages,
17 totalItems,
18 itemsPerPage,
19 onPageChange,
20 itemName = "items",
21 }) => {
22 // Generate page numbers with ellipsis
23 const generatePageNumbers = () => {
24 const pages = [];
25 const maxVisiblePages = 5;
26 let startPage = Math.max(1, currentPage - Math.floor(maxVisiblePages / 2));
27 let endPage = Math.min(totalPages, startPage + maxVisiblePages - 1);
28
29 // Adjust start if we're near the end
30 if (endPage - startPage + 1 < maxVisiblePages) {
31 startPage = Math.max(1, endPage - maxVisiblePages + 1);
32 }
33
34 // First page + ellipsis
35 if (startPage > 1) {
36 pages.push(
37 <Button
38 key={1}
39 variant={1 === currentPage ? "default" : "outline"}
40 size="sm"
41 onClick={() => onPageChange(1)}
42 className="h-8 w-8 p-0"
43 >
44 1
45 </Button>,
46 );
47 if (startPage > 2) {
48 pages.push(
49 <span key="ellipsis1" className="px-2 text-gray-500">
50 ...
51 </span>,
52 );
53 }
54 }
55
56 // Visible page range
57 for (let i = startPage; i <= endPage; i++) {
58 pages.push(
59 <Button
60 key={i}
61 variant={i === currentPage ? "default" : "outline"}
62 size="sm"
63 onClick={() => onPageChange(i)}
64 className="h-8 w-8 p-0"
65 >
66 {i}
67 </Button>,
68 );
69 }
70
71 // Ellipsis + last page
72 if (endPage < totalPages) {
73 if (endPage < totalPages - 1) {
74 pages.push(
75 <span key="ellipsis2" className="px-2 text-gray-500">
76 ...
77 </span>,
78 );
79 }
80 pages.push(
81 <Button
82 key={totalPages}
83 variant={totalPages === currentPage ? "default" : "outline"}
84 size="sm"
85 onClick={() => onPageChange(totalPages)}
86 className="h-8 w-8 p-0"
87 >
88 {totalPages}
89 </Button>,
90 );
91 }
92
93 return pages;
94 };
95
96 return (
97 <div className="flex items-center justify-between">
98 <div className="text-sm text-gray-600 dark:text-gray-400">
99 {__("Showing", "yatra")}{" "}
100 <span className="font-medium text-gray-900 dark:text-white">
101 {(currentPage - 1) * itemsPerPage + 1}
102 </span>{" "}
103 -{" "}
104 <span className="font-medium text-gray-900 dark:text-white">
105 {Math.min(currentPage * itemsPerPage, totalItems)}
106 </span>{" "}
107 {__("of", "yatra")}{" "}
108 <span className="font-medium text-gray-900 dark:text-white">
109 {totalItems}
110 </span>{" "}
111 {itemName}
112 </div>
113 <div className="flex items-center gap-1">
114 {/* Previous Button */}
115 <Button
116 variant="outline"
117 size="sm"
118 onClick={() => onPageChange(Math.max(1, currentPage - 1))}
119 disabled={currentPage === 1}
120 className="h-8 px-3"
121 >
122 {__("Previous", "yatra")}
123 </Button>
124
125 {/* Page Numbers */}
126 {generatePageNumbers()}
127
128 {/* Next Button */}
129 <Button
130 variant="outline"
131 size="sm"
132 onClick={() => onPageChange(Math.min(totalPages, currentPage + 1))}
133 disabled={currentPage >= totalPages}
134 className="h-8 px-3"
135 >
136 {__("Next", "yatra")}
137 </Button>
138 </div>
139 </div>
140 );
141 };
142