From 1a2241c40e10193c5ff7008a7b7b36cc1d855d96 Mon Sep 17 00:00:00 2001
From: joonhoekim <26rote@gmail.com>
Date: Tue, 25 Mar 2025 15:55:45 +0900
Subject: initial commit

---
 .../client-data-table/data-table-pagination.tsx    | 132 +++++++++++++++++++++
 1 file changed, 132 insertions(+)
 create mode 100644 components/client-data-table/data-table-pagination.tsx

(limited to 'components/client-data-table/data-table-pagination.tsx')

diff --git a/components/client-data-table/data-table-pagination.tsx b/components/client-data-table/data-table-pagination.tsx
new file mode 100644
index 00000000..5abd3470
--- /dev/null
+++ b/components/client-data-table/data-table-pagination.tsx
@@ -0,0 +1,132 @@
+"use client"
+
+import * as React from "react"
+import { type Table } from "@tanstack/react-table"
+import {
+  ChevronLeft,
+  ChevronRight,
+  ChevronsLeft,
+  ChevronsRight,
+} from "lucide-react"
+
+import { Button } from "@/components/ui/button"
+import {
+  Select,
+  SelectContent,
+  SelectItem,
+  SelectTrigger,
+  SelectValue,
+} from "@/components/ui/select"
+
+interface DataTablePaginationProps<TData> {
+  table: Table<TData>
+  pageSizeOptions?: Array<number | "All">
+}
+
+export function ClientDataTablePagination<TData>({
+  table,
+  pageSizeOptions = [10, 20, 30, 40, 50, "All"],
+}: DataTablePaginationProps<TData>) {
+  // 현재 테이블 pageSize
+  const currentPageSize = table.getState().pagination.pageSize
+
+  // "All"을 1,000,000으로 처리할 것이므로,
+  // 만약 현재 pageSize가 1,000,000이면 화면상 "All"로 표시
+  const selectValue =
+    currentPageSize === 1_000_000
+      ? "All"
+      : String(currentPageSize)
+
+  return (
+    <div className="flex w-full flex-col-reverse items-center justify-between gap-4 overflow-auto p-1 sm:flex-row sm:gap-8">
+      <div className="flex-1 whitespace-nowrap text-sm text-muted-foreground">
+        {table.getFilteredSelectedRowModel().rows.length} of{" "}
+        {table.getFilteredRowModel().rows.length} row(s) selected.
+      </div>
+      <div className="flex flex-col-reverse items-center gap-4 sm:flex-row sm:gap-6 lg:gap-8">
+        {/* Rows per page Select */}
+        <div className="flex items-center space-x-2">
+          <p className="whitespace-nowrap text-sm font-medium">Rows per page</p>
+          <Select
+            value={selectValue}
+            onValueChange={(value) => {
+              if (value === "All") {
+                // "All"을 1,000,000으로 치환
+                table.setPageSize(1_000_000)
+              } else {
+                table.setPageSize(Number(value))
+              }
+            }}
+          >
+            <SelectTrigger className="h-8 w-[4.5rem]">
+              <SelectValue placeholder={selectValue} />
+            </SelectTrigger>
+            <SelectContent side="top">
+              {pageSizeOptions.map((option) => {
+                // 화면에 표시할 라벨
+                const label = option === "All" ? "All" : String(option)
+                // value도 문자열화
+                const val = option === "All" ? "All" : String(option)
+
+                return (
+                  <SelectItem key={val} value={val}>
+                    {label}
+                  </SelectItem>
+                )
+              })}
+            </SelectContent>
+          </Select>
+        </div>
+
+        {/* 현재 페이지 / 전체 페이지 */}
+        <div className="flex items-center justify-center text-sm font-medium">
+          Page {table.getState().pagination.pageIndex + 1} of{" "}
+          {table.getPageCount()}
+        </div>
+
+        {/* 페이지 이동 버튼 */}
+        <div className="flex items-center space-x-2">
+          <Button
+            aria-label="Go to first page"
+            variant="outline"
+            className="hidden size-8 p-0 lg:flex"
+            onClick={() => table.setPageIndex(0)}
+            disabled={!table.getCanPreviousPage()}
+          >
+            <ChevronsLeft className="size-4" aria-hidden="true" />
+          </Button>
+          <Button
+            aria-label="Go to previous page"
+            variant="outline"
+            size="icon"
+            className="size-8"
+            onClick={() => table.previousPage()}
+            disabled={!table.getCanPreviousPage()}
+          >
+            <ChevronLeft className="size-4" aria-hidden="true" />
+          </Button>
+          <Button
+            aria-label="Go to next page"
+            variant="outline"
+            size="icon"
+            className="size-8"
+            onClick={() => table.nextPage()}
+            disabled={!table.getCanNextPage()}
+          >
+            <ChevronRight className="size-4" aria-hidden="true" />
+          </Button>
+          <Button
+            aria-label="Go to last page"
+            variant="outline"
+            size="icon"
+            className="hidden size-8 lg:flex"
+            onClick={() => table.setPageIndex(table.getPageCount() - 1)}
+            disabled={!table.getCanNextPage()}
+          >
+            <ChevronsRight className="size-4" aria-hidden="true" />
+          </Button>
+        </div>
+      </div>
+    </div>
+  )
+}
\ No newline at end of file
-- 
cgit v1.2.3

