"use client"; import { type Column, type ColumnDef, flexRender, getCoreRowModel, getPaginationRowModel, getSortedRowModel, type SortingState, type Table as TableType, useReactTable, } from "@tanstack/react-table"; import { ArrowDown, ArrowUp, ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight, ChevronsUpDown, } from "lucide-react"; import * as React from "react"; import { z } from "zod"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { cn } from "@/lib/utils"; const formatPrice = (value: number) => new Intl.NumberFormat("fa-IR", { style: "currency", currency: "IRR", }).format(value); const formatNumber = (value: number) => value.toLocaleString("fa-IR"); type UseDataTableOptions = { data: Array; columns: Array>; getRowId?: (row: TData) => string; initialSorting?: SortingState; }; export function useDataTable(options: UseDataTableOptions) { const { data, columns, getRowId, initialSorting = [] } = options; const [sorting, setSorting] = React.useState(initialSorting); const table = useReactTable({ data, columns, getRowId, state: { sorting }, onSortingChange: setSorting, getCoreRowModel: getCoreRowModel(), getSortedRowModel: getSortedRowModel(), getPaginationRowModel: getPaginationRowModel(), }); return { table, sorting, setSorting, }; } type DataTableColumnHeaderProps = { column: Column; title: string; }; export const DataTableColumnHeader = ({ column, title, }: DataTableColumnHeaderProps) => { const canSort = column.getCanSort(); const sorted = column.getIsSorted(); if (!canSort) { return ( {title} ); } return ( ); }; type DataTablePaginationProps = { table: TableType; pageSizeOptions?: number[]; }; export const DataTablePagination = ({ table, pageSizeOptions = [10, 20, 30, 40, 50], }: DataTablePaginationProps) => { const currentPage = table.getState().pagination.pageIndex; const pageSize = table.getState().pagination.pageSize; const totalRows = table.getFilteredRowModel().rows.length; const pageCount = table.getPageCount(); const startRow = currentPage * pageSize + 1; const endRow = Math.min((currentPage + 1) * pageSize, totalRows); const relevantPageSizes = pageSizeOptions.filter( (size) => size <= totalRows || size === pageSize, ); return (
{totalRows === 0 ? ( "نتیجه‌ای یافت نشد" ) : ( <> نمایش {formatNumber(startRow)} تا {formatNumber(endRow)} از{" "} {formatNumber(totalRows)} رکورد )}

تعداد در هر صفحه

صفحه {formatNumber(currentPage + 1)} از {formatNumber(pageCount)}
); }; export const schema = z.object({ id: z.string(), item: z.string(), type: z.string(), stock: z.boolean(), sku: z.string(), price: z.number(), availability: z.array(z.enum(["فروشگاه", "آنلاین"])), }); const data = [ { id: "prod-001", item: "قاب تبلت", type: "الکترونیک", stock: true, sku: "TC-001", price: 83.24, availability: ["فروشگاه", "آنلاین"], }, { id: "prod-002", item: "ساعت هوشمند", type: "الکترونیک", stock: true, sku: "SW-002", price: 246.27, availability: ["فروشگاه", "آنلاین"], }, { id: "prod-003", item: "پلیور پشمی", type: "لوازم جانبی", stock: true, sku: "WS-003", price: 168.27, availability: ["فروشگاه"], }, { id: "prod-004", item: "هدفون بی‌سیم", type: "الکترونیک", stock: true, sku: "WE-004", price: 107.75, availability: ["فروشگاه", "آنلاین"], }, { id: "prod-005", item: "کاور لپ‌تاپ", type: "الکترونیک", stock: true, sku: "LS-005", price: 248.02, availability: ["فروشگاه", "آنلاین"], }, { id: "prod-006", item: "کفش دویدن", type: "کفش", stock: true, sku: "RS-006", price: 208.26, availability: ["فروشگاه"], }, { id: "prod-007", item: "کاپشن زمستانی", type: "پوشاک", stock: true, sku: "WJ-007", price: 148.06, availability: ["فروشگاه"], }, { id: "prod-008", item: "قاب گوشی", type: "لوازم جانبی", stock: true, sku: "PC-008", price: 298.08, availability: ["فروشگاه", "آنلاین"], }, { id: "prod-009", item: "ردیاب تناسب اندام", type: "پوشاک", stock: true, sku: "FT-009", price: 222.09, availability: ["فروشگاه"], }, { id: "prod-010", item: "عینک آفتابی", type: "لوازم جانبی", stock: true, sku: "SG-010", price: 60.17, availability: ["فروشگاه"], }, { id: "prod-011", item: "بوت روزمره", type: "کفش", stock: true, sku: "CB-011", price: 276.15, availability: ["فروشگاه", "آنلاین"], }, { id: "prod-012", item: "کفش پاشنه‌بلند", type: "پوشاک", stock: true, sku: "HH-012", price: 85.47, availability: ["فروشگاه"], }, { id: "prod-013", item: "صندل ساحلی", type: "کفش", stock: true, sku: "BS-013", price: 41.25, availability: ["فروشگاه", "آنلاین"], }, { id: "prod-014", item: "گردنبند طلا", type: "لوازم جانبی", stock: true, sku: "GN-014", price: 201.47, availability: ["فروشگاه", "آنلاین"], }, { id: "prod-015", item: "اسپیکر بلوتوث", type: "الکترونیک", stock: true, sku: "BS-015", price: 297.37, availability: ["فروشگاه", "آنلاین"], }, ]; export const validatedData = schema.array().parse(data); export const columns: ColumnDef>[] = [ { accessorKey: "sku", header: ({ column }) => ( ), enableSorting: true, enableHiding: false, }, { accessorKey: "item", header: ({ column }) => ( ), cell: ({ row }) => (
{row.getValue("item")}
), enableSorting: true, enableHiding: false, }, { accessorKey: "type", header: ({ column }) => ( ), enableSorting: true, enableHiding: false, }, { accessorKey: "stock", header: ({ column }) => ( ), cell: ({ row }) => { const inStock: boolean = row.getValue("stock"); return inStock ? "بله" : "خیر"; }, enableSorting: false, enableHiding: false, }, { accessorKey: "price", header: ({ column }) => ( ), cell: ({ row }) => { const price = parseFloat(row.getValue("price")); return
{formatPrice(price)}
; }, enableSorting: true, enableHiding: false, }, { accessorKey: "availability", header: ({ column }) => ( ), cell: ({ row }) => { const availability: ("فروشگاه" | "آنلاین")[] = row.getValue("availability"); return (
{availability.map((location) => ( {location} ))}
); }, enableSorting: false, enableHiding: false, }, ]; export const DataTable7 = ({ className }: { className?: string }) => { const { table } = useDataTable({ data: validatedData, columns, getRowId: (row) => row.id.toString(), }); return (

جدول با صفحه‌بندی کامل

جدول داده با مرتب‌سازی، انتخاب تعداد رکورد در هر صفحه، نمایش شماره صفحه و دکمه‌های ناوبری کامل. مناسب برای مجموعه‌داده‌های بزرگ با کنترل دقیق صفحه‌بندی.

{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( {header.isPlaceholder ? null : flexRender( header.column.columnDef.header, header.getContext(), )} ); })} ))} {table.getRowModel().rows?.length ? ( table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => ( {flexRender( cell.column.columnDef.cell, cell.getContext(), )} ))} )) ) : ( نتیجه‌ای یافت نشد. )}
); };