### Install Shadcn UI Base Components Source: https://context7.com/jacksonkasi1/tnks-data-table/llms.txt Before installing the data-table component, ensure you have the necessary Shadcn UI base components installed. This command initializes Shadcn UI in your project. ```bash npx shadcn@latest init ``` ```bash npx shadcn@latest add button checkbox input select popover calendar dropdown-menu separator table command ``` -------------------------------- ### Install Shadcn UI Components Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Use the Shadcn CLI to initialize Shadcn UI and install all required base components for the data table. Do not copy these manually. ```bash # Initialize Shadcn UI (if you haven't already) npx shadcn@latest init # Install all required components in one command npx shadcn@latest add alert avatar badge button calendar checkbox command dialog dropdown-menu form input label popover select separator skeleton sonner table ``` -------------------------------- ### CamelCase API Example Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Illustrates column and table configuration setup for APIs using camelCase. The accessorKeys and defaultSortBy should directly correspond to the API's camelCase field names. ```typescript // API Response { "data": [ { "id": 1, "userName": "John Doe", "createdAt": "2023-01-01T10:00:00Z", "totalExpenses": "1234.56" } ] } // Column Definitions (matches API exactly) { accessorKey: "userName", // ✅ Matches API field header: "Name" } { accessorKey: "createdAt", // ✅ Matches API field header: "Created" } // Table Configuration config={{ defaultSortBy: "createdAt", // ✅ Matches API field // ... other options }} ``` -------------------------------- ### Install Dependencies and Run Checks Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/CODE_QUALITY_REPORT.md Install project dependencies and run essential checks like type checking, linting, and building. These commands are typically run locally before testing or deployment. ```bash npm install npm run typecheck npm run lint npm run build ``` -------------------------------- ### Install Shadcn UI Components and Data Table Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Install required Shadcn UI components and the data-table component using the Shadcn CLI. Ensure table styles are added to your globals.css. ```bash npx shadcn@latest init npx shadcn@latest add button checkbox input select popover calendar dropdown-menu separator table command npx shadcn@latest add https://tnks-data-table.vercel.app/r/data-table.json npx shadcn@latest add https://tnks-data-table.vercel.app/r/calendar-date-picker.json ``` -------------------------------- ### Install tnks-data-table and Calendar Component Source: https://context7.com/jacksonkasi1/tnks-data-table/llms.txt Install the data-table component and its companion CalendarDatePicker component using the Shadcn CLI. This command fetches the component definitions from the provided registry URL. ```bash npx shadcn@latest add https://tnks-data-table.vercel.app/r/data-table.json ``` ```bash npx shadcn@latest add https://tnks-data-table.vercel.app/r/calendar-date-picker.json ``` -------------------------------- ### Install Core Data Table Dependencies with npm Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Install the core npm packages required for the data table functionality, including react-table, react-query, and form handling libraries. ```bash npm install @tanstack/react-table @tanstack/react-query @hookform/resolvers react-hook-form zod sonner date-fns date-fns-tz xlsx class-variance-authority clsx tailwind-merge lucide-react npm install @radix-ui/react-avatar @radix-ui/react-checkbox @radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react-icons @radix-ui/react-label @radix-ui/react-popover @radix-ui/react-select @radix-ui/react-separator @radix-ui/react-slot npm install react-day-picker cmdk npm install @types/xlsx npm install --save-dev @tanstack/eslint-plugin-query ``` -------------------------------- ### Name-based Sorting Example Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Example of configuring a DataTable for alphabetical sorting by a 'name' column in ascending order. ```typescript // Alphabetical ordering defaultSortBy: "name", defaultSortOrder: "asc" ``` -------------------------------- ### Add Entity Page Setup Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Sets up the main page component for managing entities, including metadata and suspense for the entity table. ```typescript // src/app/(section)/entities/page.tsx import { Metadata } from "next"; import { Suspense } from "react"; import EntityTable from "./entity-table"; export const metadata: Metadata = { title: "Entities Management", }; export default function EntitiesPage() { return (

Entities List

Loading...}>
); } ``` -------------------------------- ### Complete TNKS Data Table Example Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md A full example demonstrating the TNKS Data Table with row selection, toolbar options, data fetching, and conditional row click handling for navigation or modal display. Ensure all imported components and functions are correctly defined. ```typescript // src/app/(section)/users/users-table/index.tsx "use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { DataTable } from "@/components/data-table/data-table"; import { User } from "./schema"; import { UserDetailModal } from "./components/user-detail-modal"; export default function UsersTable() { const router = useRouter(); const [selectedUser, setSelectedUser] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); // Handle row clicks with conditional logic const handleRowClick = (user: User, rowIndex: number) => { // Option 1: Navigate to detail page if (user.role === 'admin') { router.push(`/admin/users/${user.id}`); return; } // Option 2: Open modal for regular users setSelectedUser(user); setIsModalOpen(true); }; return ( <> getColumns={getColumns} exportConfig={useExportConfig()} fetchDataFn={useUsersData} fetchByIdsFn={fetchUsersByIds} idField="id" onRowClick={handleRowClick} renderToolbarContent={({ selectedRows, allSelectedIds, totalSelectedCount, resetSelection }) => ( )} config={{ enableRowSelection: true, enableSearch: true, enableDateFilter: true, enableColumnVisibility: true, enableUrlState: true, }} /> ); } ``` -------------------------------- ### Install Core Data Table Dependencies with Bun Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Install the core npm packages required for the data table functionality using Bun. This includes react-table, react-query, and form handling libraries. ```bash bun add @tanstack/react-table @tanstack/react-query @hookform/resolvers react-hook-form zod sonner date-fns date-fns-tz xlsx class-variance-authority clsx tailwind-merge lucide-react @radix-ui/react-avatar @radix-ui/react-checkbox @radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react-icons @radix-ui/react-label @radix-ui/react-popover @radix-ui/react-select @radix-ui/react-separator @radix-ui/react-slot react-day-picker cmdk @types/xlsx ``` -------------------------------- ### Priority-based Sorting Example Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Example of configuring a DataTable to sort by a 'priority' column in descending order, showing high priority items first. ```typescript // Show high priority items first defaultSortBy: "priority", defaultSortOrder: "desc" ``` -------------------------------- ### Row Click Navigation Example Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Example of using the 'onRowClick' handler for navigation. It utilizes 'useRouter' from 'next/navigation' to redirect to a user detail page based on the clicked row's ID. ```typescript import { useRouter } from 'next/navigation'; function UsersTable() { const router = useRouter(); const handleRowClick = (user: User, rowIndex: number) => { // Navigate to user detail page router.push(`/users/${user.id}`); }; return ( // ... other props onRowClick={handleRowClick} /> ); } ``` -------------------------------- ### Install Core Data Table Dependencies with pnpm Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Install the core npm packages required for the data table functionality using pnpm. This includes react-table, react-query, and form handling libraries. ```bash pnpm add @tanstack/react-table @tanstack/react-query @hookform/resolvers react-hook-form zod sonner date-fns date-fns-tz xlsx class-variance-authority clsx tailwind-merge lucide-react @radix-ui/react-avatar @radix-ui/react-checkbox @radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react-icons @radix-ui/react-label @radix-ui/react-popover @radix-ui/react-select @radix-ui/react-separator @radix-ui/react-slot react-day-picker cmdk @types/xlsx ``` -------------------------------- ### React Query Provider Setup Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Configure the React Query provider by wrapping your root layout with QueryClientProvider. This sets up default options for queries, such as staleTime and retry behavior. ```typescript // src/app/layout.tsx or your root layout "use client"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { useState } from "react"; export default function RootLayout({ children, }: { children: React.ReactNode; }) { const [queryClient] = useState(() => new QueryClient({ defaultOptions: { queries: { staleTime: 60 * 1000, // 1 minute retry: false, }, }, })); return ( {children} ); } ``` -------------------------------- ### DataTable Component Example Source: https://context7.com/jacksonkasi1/tnks-data-table/llms.txt A complete working example demonstrating the integration of the DataTable component with React Query for data fetching and Zod for schema validation. Includes API fetch function, React Query hook, column definitions, and export configuration. ```tsx "use client"; import { DataTable } from "@/components/data-table/data-table"; import { ColumnDef } from "@tanstack/react-table"; import { useQuery, keepPreviousData } from "@tanstack/react-query"; import { z } from "zod"; import { Checkbox } from "@/components/ui/checkbox"; import { DataTableColumnHeader } from "@/components/data-table/column-header"; // 1. Define schema with Zod const userSchema = z.object({ id: z.number(), name: z.string(), email: z.string(), created_at: z.string(), expense_count: z.number(), total_expenses: z.string(), }); type User = z.infer; const usersResponseSchema = z.object({ success: z.boolean(), data: z.array(userSchema), pagination: z.object({ page: z.number(), limit: z.number(), total_pages: z.number(), total_items: z.number(), }), }); // 2. API fetch function async function fetchUsers({ page = 1, limit = 10, search = "", from_date = "", to_date = "", sort_by = "created_at", sort_order = "desc" }) { const params = new URLSearchParams({ page: String(page), limit: String(limit), sort_by, sort_order }); if (search) params.set("search", search); if (from_date) params.set("from_date", from_date); if (to_date) params.set("to_date", to_date); const res = await fetch(`/api/users?${params}`); if (!res.ok) throw new Error(res.statusText); return usersResponseSchema.parse(await res.json()); } // 3. React Query hook (mark with isQueryHook = true) function useUsersData(page: number, pageSize: number, search: string, dateRange: { from_date: string; to_date: string }, sortBy: string, sortOrder: string) { return useQuery({ queryKey: ["users", page, pageSize, search, dateRange, sortBy, sortOrder], queryFn: () => fetchUsers({ page, limit: pageSize, search, from_date: dateRange.from_date, to_date: dateRange.to_date, sort_by: sortBy, sort_order: sortOrder }), placeholderData: keepPreviousData, }); } useUsersData.isQueryHook = true; // Required flag // 4. Fetch by IDs (for cross-page selection/export) async function fetchUsersByIds(ids: number[]): Promise { const params = new URLSearchParams(); ids.forEach(id => params.append("id", String(id))); const res = await fetch(`/api/users/by-ids?${params}`); const data = await res.json(); return data.data; } // 5. Column definitions const getColumns = (handleRowDeselection: ((rowId: string) => void) | null | undefined): ColumnDef[] => { const base: ColumnDef[] = [ { accessorKey: "id", header: ({ column }) => , size: 70 }, { accessorKey: "name", header: ({ column }) => , size: 200 }, { accessorKey: "email", header: ({ column }) => , size: 250 }, { accessorKey: "created_at", header: ({ column }) => , size: 120 }, ]; if (handleRowDeselection === null) return base; return [ { id: "select", header: ({ table }) => ( table.toggleAllPageRowsSelected(!!v)} aria-label="Select all" /> ), cell: ({ row }) => ( { row.toggleSelected(!!v); if (!v) handleRowDeselection?.(row.id); }} aria-label="Select row" /> ), enableSorting: false, enableHiding: false, size: 50, }, ...base, ]; }; // 6. Export config const exportConfig = { entityName: "users", headers: ["id", "name", "email", "created_at"], columnMapping: { id: "ID", name: "Name", email: "Email", created_at: "Joined Date" }, columnWidths: [{ wch: 10 }, { wch: 20 }, { wch: 30 }, { wch: 20 }], }; // 7. Render the DataTable export default function UserTable() { return ( getColumns={getColumns} fetchDataFn={useUsersData} fetchByIdsFn={fetchUsersByIds} exportConfig={exportConfig} idField="id" pageSizeOptions={[10, 20, 50, 100]} onRowClick={(user, idx) => console.log("Clicked", user.name, "at row", idx)} config={{ enableRowSelection: true, enableClickRowSelect: false, enableKeyboardNavigation: true, enableSearch: true, enableDateFilter: true, enableColumnVisibility: true, enableUrlState: true, }} /> ); } ``` -------------------------------- ### Row Click Modal/Dialog Example Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Example of using 'onRowClick' to open a modal or dialog. It sets the selected user state and toggles the modal's visibility when a row is clicked. ```typescript function UsersTable() { const [selectedUser, setSelectedUser] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); const handleRowClick = (user: User, rowIndex: number) => { setSelectedUser(user); setIsModalOpen(true); }; return ( <> // ... other props onRowClick={handleRowClick} /> ); } ``` -------------------------------- ### Snake_case API Example Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Demonstrates how to define columns and table configuration when your API response uses snake_case. Ensure accessorKeys and defaultSortBy exactly match the API field names. ```typescript // API Response { "data": [ { "id": 1, "user_name": "John Doe", "created_at": "2023-01-01T10:00:00Z", "total_expenses": "1234.56" } ] } // Column Definitions (matches API exactly) { accessorKey: "user_name", // ✅ Matches API field header: "Name" } { accessorKey: "created_at", // ✅ Matches API field header: "Created" } // Table Configuration config={{ defaultSortBy: "created_at", // ✅ Matches API field // ... other options }} ``` -------------------------------- ### Example Exported Data Row Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Illustrates the format of an exported data row, including both original and newly calculated columns with their mapped headers. ```text Customer ID | Full Name | Email | Phone | Age | Join Date | Total Transactions | Total Spending | Account Status | Customer Tier | Years as Customer | Spending Category | Risk Assessment 1 | John Doe | john@example.com | (555) 123-4567 | 32 | 15/01/2023 10:30 AM | 15 | $2,450.75 | ACTIVE | PREMIUM | 1 | HIGH_SPENDER | LOW_RISK ``` -------------------------------- ### Customize Toolbar with Custom Components Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Implement custom components for the toolbar area. This example shows how to add buttons for actions like adding entities or bulk deletion. ```typescript "use client"; import * as React from "react"; import { Button } from "@/components/ui/button"; import { AddEntityPopup } from "./actions/add-entity-popup"; import { BulkDeletePopup } from "./actions/bulk-delete-popup"; interface ToolbarOptionsProps { selectedEntities: { id: number; name: string }[]; allSelectedIds?: number[]; totalSelectedCount: number; resetSelection: () => void; } export const ToolbarOptions = ({ selectedEntities, allSelectedIds = [], totalSelectedCount, resetSelection, }: ToolbarOptionsProps) => { const [deleteDialogOpen, setDeleteDialogOpen] = React.useState(false); return (
{totalSelectedCount > 0 && ( <> )}
); }; ``` -------------------------------- ### List Endpoint GET Request Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Defines the GET request for the list endpoint, including optional parameters for searching, filtering by date, sorting, and pagination. ```http GET /api/entities ``` -------------------------------- ### Install Core Data Table Dependencies with Yarn Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Install the core npm packages required for the data table functionality using Yarn. This includes react-table, react-query, and form handling libraries. ```bash yarn add @tanstack/react-table @tanstack/react-query @hookform/resolvers react-hook-form zod sonner date-fns date-fns-tz xlsx class-variance-authority clsx tailwind-merge lucide-react @radix-ui/react-avatar @radix-ui/react-checkbox @radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react-icons @radix-ui/react-label @radix-ui/react-popover @radix-ui/react-select @radix-ui/react-separator @radix-ui/react-slot react-day-picker cmdk @types/xlsx ``` -------------------------------- ### Date-based Sorting Example Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Example of configuring a DataTable to sort by date in descending order, showing the newest records first. Use 'created_at' or 'createdAt' based on your API's case convention. ```typescript // Show newest records first defaultSortBy: "created_at", // or "createdAt" for camelCase defaultSortOrder: "desc" ``` -------------------------------- ### Example Column Definition for Data Table Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Demonstrates a column definition for a data table, including accessor key, custom header and cell rendering, and configuration for sorting and hiding. ```typescript { accessorKey: "name", header: ({ column }) => ( ), cell: ({ row }) => { // Custom rendering with additional styling or components return (
{row.getValue("name")}
); }, enableSorting: true, enableHiding: true, size: 200, } ``` -------------------------------- ### Install npm Dependencies for tnks-data-table Source: https://context7.com/jacksonkasi1/tnks-data-table/llms.txt Alternatively, you can manually install the required npm dependencies for the Advanced Data Table component. This includes libraries for React Table, state management, form handling, UI utilities, and date manipulation. ```bash npm install @tanstack/react-table @tanstack/react-query @hookform/resolvers react-hook-form zod \ sonner date-fns date-fns-tz exceljs class-variance-authority clsx tailwind-merge lucide-react \ @radix-ui/react-checkbox @radix-ui/react-dialog @radix-ui/react-dropdown-menu \ @radix-ui/react-popover @radix-ui/react-select @radix-ui/react-separator react-day-picker cmdk ``` -------------------------------- ### Client-Side DataTable Configuration for Cross-Page Selection Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md This example shows how to configure the DataTable component to enable cross-page selection and fetching by IDs. It requires the `fetchOrdersByIds` function to be imported and passed to the `fetchByIdsFn` prop, and `subRowsConfig` to be enabled. ```typescript import { fetchOrdersByIds } from "@/api/order/fetch-orders-by-ids"; ``` -------------------------------- ### Server-Side Pagination Response Structure Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Example JSON structure for server-side pagination response, including current page, items per page, total pages, and total items. ```json { "success": true, "data": [...], "pagination": { "page": 1, "limit": 10, "total_pages": 5, "total_items": 48 } } ``` -------------------------------- ### Configure React Query for Data Fetching Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Optimize data fetching using React Query by configuring `queryKey`, `queryFn`, `placeholderData`, `staleTime`, and `refetchOnWindowFocus`. This setup enables automatic caching, background refetching, and stale data management. ```typescript useQuery({ queryKey: ["entities", ...], // Include all filters in the queryKey queryFn: () => fetchEntities({...}), placeholderData: keepPreviousData, // Show previous data while loading new data staleTime: 30000, // Data is considered fresh for 30 seconds refetchOnWindowFocus: false, // Disable refetching when window regains focus }) ``` -------------------------------- ### Basic Data Formatting for Export Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Example of using a `DataTransformFunction` to format existing data fields during export. This includes timestamp and currency formatting, requiring specific utility functions. ```typescript import { DataTransformFunction } from "@/components/data-table/utils/export-utils"; import { formatTimestampToReadable, formatCurrency } from "@/utils/format"; const transformFunction: DataTransformFunction = (row: User) => ({ ...row, // Format existing columns created_at: formatTimestampToReadable(row.created_at), // "01/15/2023 10:30 AM" total_expenses: formatCurrency(row.total_expenses), // "$1,234.56" phone: formatPhoneNumber(row.phone), // "(123) 456-7890" }); ``` -------------------------------- ### Camel Case API Request Parameters Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Example of API request parameters using camelCase, matching column definitions. Ensure 'sortBy' and 'sortOrder' match your accessorKey case format. ```typescript // Column Definition { accessorKey: "createdAt" } // API Request Parameters { "search": "john", "sortBy": "createdAt", // ✅ Matches column case "sortOrder": "desc", "page": 1, "limit": 10 } ``` -------------------------------- ### API Response Structure for Orders with Subrows Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Example of an API response structure where parent rows (orders) contain subrows (product items). Each subrow can have its own set of properties. ```typescript { success: true, data: [ { id: 1, order_id: "ORD-00001", customer_name: "John Doe", product_name: "Laptop", // First product shown in parent row quantity: 1, price: "999.99", total_amount: "2499.97", subRows: [ { id: 2, order_id: "ORD-00001", product_name: "Mouse", // Additional products as subrows quantity: 2, price: "25.00" }, // ... more items ] } ] } ``` -------------------------------- ### Basic DataTable with Row Click Handling Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Example of integrating the DataTable component with basic row click handling. The 'onRowClick' prop accepts a callback function that receives row data and index. ```typescript getColumns={getColumns} exportConfig={useExportConfig()} fetchDataFn={useEntitiesData} fetchByIdsFn={fetchEntitiesByIds} idField="id" onRowClick={(rowData, rowIndex) => { console.log('Clicked row:', rowData); console.log('Row index:', rowIndex); }} config={{ enableRowSelection: true, enableSearch: true, enableDateFilter: true, }} /> ``` -------------------------------- ### Snake Case API Request Parameters Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Example of API request parameters using snake_case, matching column definitions. Ensure 'sort_by' and 'sort_order' match your accessorKey case format. ```typescript // Column Definition { accessorKey: "created_at" } // API Request Parameters { "search": "john", "sort_by": "created_at", // ✅ Matches column case "sort_order": "desc", "page": 1, "limit": 10 } ``` -------------------------------- ### Hono.js Server-Side API Implementation for Data Table Source: https://context7.com/jacksonkasi1/tnks-data-table/llms.txt Example implementation of a server-side API endpoint using Hono.js that handles filtering, sorting, pagination, and returns data in the expected JSON format for a data table. ```typescript // Expected GET /api/entities query parameters: // ?search=alice&from_date=2024-01-01&to_date=2024-12-31 // &sort_by=created_at&sort_order=desc&page=2&limit=20 // Expected JSON response: // { // "success": true, // "data": [ { "id": 1, "name": "Alice", ... }, ... ], // "pagination": { "page": 2, "limit": 20, "total_pages": 10, "total_items": 196 } // } // Example Hono.js server implementation (src/api/users route): import { Hono } from "hono"; import { db } from "@/db"; import { users } from "@/db/schema"; import { like, gte, lte, asc, desc, count } from "drizzle-orm"; const router = new Hono(); router.get("/", async (c) => { const { search = "", from_date, to_date, sort_by = "created_at", sort_order = "desc", page = "1", limit = "10" } = c.req.query(); const pageNum = Math.max(1, parseInt(page)); const limitNum = Math.min(100, parseInt(limit)); const offset = (pageNum - 1) * limitNum; const where = []; if (search) where.push(like(users.name, `%${search}%`)); if (from_date) where.push(gte(users.created_at, new Date(from_date))); if (to_date) where.push(lte(users.created_at, new Date(to_date))); const orderFn = sort_order === "asc" ? asc : desc; const sortCol = users[sort_by as keyof typeof users] ?? users.created_at; const [data, [{ total }]] = await Promise.all([ db.select().from(users).where(...where).orderBy(orderFn(sortCol)).limit(limitNum).offset(offset), db.select({ total: count() }).from(users).where(...where), ]); return c.json({ success: true, data, pagination: { page: pageNum, limit: limitNum, total_pages: Math.ceil(total / limitNum), total_items: total }, }); }); // Error response format (consistent across all endpoints): // { "success": false, "error": "Not found", "details": [] } // HTTP 400 (validation), 404 (not found), 409 (conflict), 500 (server error) ``` -------------------------------- ### Run Seed Script Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/src/scripts/README.md Execute the database seeding script using npm. Ensure your .env file is configured with the correct database connection string. ```bash # Run the seed script npm run seed ``` -------------------------------- ### Add Data Table Component from Local Registry Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Use this command to add the data-table component from a local development server. Ensure the server is running at http://localhost:3000. ```bash npx shadcn@latest add http://localhost:3000/r/data-table.json ``` ```bash npx shadcn@latest add http://localhost:3000/r/calendar-date-picker.json ``` -------------------------------- ### Migration from Complex Case Systems Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Shows the recommended approach for migrating from systems requiring manual case conversion to the direct matching method. Use accessorKeys that precisely match your API response fields. ```typescript // ❌ Old Complex Way (don't do this) { accessorKey: "userName", // camelCase column apiField: "user_name", // snake_case API needsConversion: true } // ✅ New Simple Way (recommended) { accessorKey: "user_name" // Matches API exactly header: "User Name" // Human readable display } ``` -------------------------------- ### Implement Virtualized Rendering with useVirtualizer Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Use the `useVirtualizer` hook for efficient rendering of large tables. Ensure the `tableContainerRef` is correctly attached to a scrollable container and `estimateSize` is set to an approximate row height. ```tsx import { useVirtualizer } from "@tanstack/react-virtual"; // Inside your component: const tableContainerRef = React.useRef(null); const rowVirtualizer = useVirtualizer({ count: rows.length, getScrollElement: () => tableContainerRef.current, estimateSize: () => 35, // Approximate row height overscan: 10, }); // Use with your table:
{/* ... */} {rowVirtualizer.getVirtualItems().map((virtualRow) => { const row = rows[virtualRow.index]; return ( {/* Render cells */} ); })}
``` -------------------------------- ### Subrow Column Definitions Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Example of defining distinct columns for subrows when using the 'custom-columns' mode. ```typescript const getStopColumns = () => [ { id: "stop_number", header: "#" }, { id: "stop_type", header: "Type" }, { id: "location_name", header: "Location" }, { id: "scheduled_time", header: "Scheduled" }, { id: "status", header: "Status" }, // ... more stop columns ]; ``` -------------------------------- ### Parent Column Definitions Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Example of defining columns for the parent rows in a data table using the 'custom-columns' mode. ```typescript const getParentColumns = () => [ { id: "booking_id", header: "Booking ID" }, { id: "customer_name", header: "Customer" }, { id: "pickup_location", header: "From" }, { id: "delivery_location", header: "To" }, { id: "total_stops", header: "Stops" }, { id: "total_amount", header: "Amount" }, // ... more parent columns ]; ``` -------------------------------- ### Get Orders By IDs Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Fetches specific orders by their IDs, useful for cross-page selection and export functionality. This endpoint retrieves orders and their associated items. ```APIDOC ## GET /api/orders/by-ids ### Description Fetches a list of orders based on a comma-separated list of order IDs. This is useful for selecting and exporting items across different pages. ### Method GET ### Endpoint /api/orders/by-ids ### Query Parameters - **ids** (string) - Required - A comma-separated string of order IDs (e.g., "1,2,3,4,5"). ### Response #### Success Response (200) - **success** (boolean) - Indicates if the request was successful. - **data** (array) - An array of order objects, each potentially containing `subRows` (order items). ### Response Example ```json { "success": true, "data": [ { "order_id": 1, "customer_name": "John Doe", "total_items": 5, "total_amount": 100.50, "subRows": [ { "order_id": 1, "product_name": "Widget", "quantity": 2, "price": 25.25, "subtotal": 50.50 } ] } ] } ``` ``` -------------------------------- ### Get Grouped Orders Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Fetches orders with their associated items, supporting pagination, searching, and sorting. This endpoint is designed for server-side rendering of data tables. ```APIDOC ## GET /api/orders/grouped ### Description Fetches a paginated list of orders, including their associated items (subRows). Supports filtering, searching, and sorting. ### Method GET ### Endpoint /api/orders/grouped ### Query Parameters - **page** (number) - Optional - The page number to retrieve. - **limit** (number) - Optional - The number of items per page. - **search** (string) - Optional - The search term to filter orders. - **sort_by** (string) - Optional - The field to sort orders by. - **sort_order** (string) - Optional - The order to sort by ('asc' or 'desc'). ### Response #### Success Response (200) - **success** (boolean) - Indicates if the request was successful. - **data** (array) - An array of order objects, each potentially containing `subRows` (order items). - **pagination** (object) - Pagination details including `page`, `limit`, `total_pages`, and `total_items`. ### Request Example ```json { "example": "/api/orders/grouped?page=1&limit=10&search=example&sort_by=order_id&sort_order=asc" } ``` ### Response Example ```json { "success": true, "data": [ { "order_id": 1, "customer_name": "John Doe", "total_items": 5, "total_amount": 100.50, "subRows": [ { "order_id": 1, "product_name": "Widget", "quantity": 2, "price": 25.25, "subtotal": 50.50 } ] } ], "pagination": { "page": 1, "limit": 10, "total_pages": 5, "total_items": 50 } } ``` ``` -------------------------------- ### Batch Query for Subrows Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Demonstrates an efficient way to fetch all items for multiple orders using a single database query, avoiding the N+1 query problem. This is recommended for performance when dealing with subrows. ```typescript // Single query to fetch all items for multiple orders const allItems = await db .select() .from(orderItems) .where(sql`${orderItems.order_id} IN ${orderIds}`); ``` -------------------------------- ### Data Table Directory Structure Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md This outlines the directory structure and files for the core data table components, including headers, export, resizing, main table, pagination, toolbar, and view options. ```bash src/components/data-table/ ├── column-header.tsx # Sortable column headers ├── data-export.tsx # Export functionality UI ├── data-table-resizer.tsx # Column resize handler ├── data-table.tsx # Main data table component ├── pagination.tsx # Pagination controls ├── toolbar.tsx # Table toolbar with filters ├── view-options.tsx # Column visibility options ├── hooks/ │ └── use-table-column-resize.ts # Column resize hook └── utils/ ├── case-utils.ts # Case format conversion utilities ├── column-sizing.ts # Column sizing utilities ├── conditional-state.ts # Conditional state management ├── date-format.ts # Date formatting utilities ├── deep-utils.ts # Deep object utilities ├── export-utils.ts # Export functionality ├── index.ts # Utility exports ├── keyboard-navigation.ts # Keyboard navigation ├── search.ts # Search utilities ├── table-config.ts # Table configuration ├── table-state-handlers.ts # State handlers └── url-state.ts # URL state management ``` -------------------------------- ### Configure Table Styles Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Apply these CSS styles to configure transitions for opacity and color, and to enable hover effects on resizable table elements. ```css transition: opacity 0.15s ease, color 0.15s ease; } .resizable-table [data-resizing]:hover svg { opacity: 1 !important; color: hsl(var(--primary)) !important; } } ``` -------------------------------- ### Implement Data Table with Custom Filters Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Demonstrates how to integrate a data table with custom filter components, such as a status selector. Requires 'client' component directive and necessary imports for UI elements and data fetching. ```tsx "use client"; import * as React from "react"; import { DataTable } from "@/components/data-table/data-table"; import { getColumns } from "./components/columns"; import { useExportConfig } from "./utils/config"; import { fetchOrdersByIds } from "@/api/order/fetch-orders-by-ids"; import { useOrdersData } from "./utils/data-fetching"; import { ToolbarOptions } from "./components/toolbar-options"; import { Order, OrderStatus } from "./schema"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Badge } from "@/components/ui/badge"; import { X } from "lucide-react"; export default function OrdersTable() { const [statusFilter, setStatusFilter] = React.useState ("all"); // Custom function that extends the base query to add the status filter const fetchOrdersWithStatus = React.useCallback( ( page: number, pageSize: number, search: string, dateRange: any, sortBy: string, sortOrder: string ) => { return useOrdersData( page, pageSize, search, dateRange, sortBy, sortOrder, statusFilter === "all" ? undefined : statusFilter ); }, [statusFilter] ); // Set isQueryHook property to true to match the DataTable expectations fetchOrdersWithStatus.isQueryHook = true; // Custom filters to render in the toolbar const renderCustomFilters = () => (
{statusFilter !== "all" && ( Status: {statusFilter} setStatusFilter("all")} /> )}
); return ( getColumns={getColumns} exportConfig={useExportConfig()} fetchDataFn={fetchOrdersWithStatus} fetchByIdsFn={fetchOrdersByIds} idField="id" pageSizeOptions={[10, 20, 50, 100]} renderToolbarContent={({ selectedRows, allSelectedIds, totalSelectedCount, resetSelection, }) => (
{renderCustomFilters()}
({ id: row.id, reference: row.reference, }))} allSelectedIds={allSelectedIds} totalSelectedCount={totalSelectedCount} resetSelection={resetSelection} />
)} config={{ enableRowSelection: true, enableSearch: true, enableDateFilter: true, enableColumnVisibility: true, enableUrlState: true, }} /> ); } ``` -------------------------------- ### Create Response Format Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md The expected JSON format for a successful response from the create endpoint, including the newly created entity's data. ```json { "success": true, "data": { "id": 49, "name": "New Entity", "email": "new@example.com", "created_at": "2025-04-14T06:44:16Z", ... } } ``` -------------------------------- ### Clone TNKS Data Table Repository for Local Development Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Clone the TNKS Data Table repository to your local machine to set up the component for development or testing purposes. ```bash git clone https://github.com/jacksonkasi1/tnks-data-table.git cd tnks-data-table ``` -------------------------------- ### Accessing Selected Rows in Toolbar Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md Example of using the 'renderToolbarContent' prop to access and display information about selected rows. Provides selected rows, all selected IDs, total count, and a reset function. ```typescript renderToolbarContent={({ selectedRows, // Currently visible selected rows allSelectedIds, // All selected IDs across pages totalSelectedCount, // Total number of selected items resetSelection // Function to reset selection }) => ( )} ``` -------------------------------- ### Customize Data Table Column Rendering with React Source: https://github.com/jacksonkasi1/tnks-data-table/blob/main/README.md This example demonstrates how to customize the rendering of a 'status' column in a data table. It maps different status strings to corresponding `Badge` variants for visual representation. ```typescript { accessorKey: "status", header: ({ column }) => ( ), cell: ({ row }) => { const status = row.getValue("status") as string; // Map status to badge variant const variant = { active: "success", inactive: "secondary", pending: "warning", error: "destructive", }[status] || "outline"; return (
{status}
); }, size: 100, } ```