### REST API for Skaters with cURL Examples Source: https://context7.com/sadmann7/shadcn-table/llms.txt Provides examples of interacting with a REST API endpoint for skaters using cURL. This endpoint supports fetching all skaters, creating single or bulk skaters, bulk updates, and bulk deletions. ```bash # GET - Fetch all skaters curl http://localhost:3000/api/skaters # POST - Create single skater curl -X POST http://localhost:3000/api/skaters \ -H "Content-Type: application/json" \ -d '{ "name": "Tony Hawk", "email": "tony@hawk.com", "stance": "goofy", "style": "vert", "status": "legend", "yearsSkating": 40, "isPro": true }' # POST - Bulk create skaters curl -X POST http://localhost:3000/api/skaters \ -H "Content-Type: application/json" \ -d '{ "skaters": [ { "name": "Skater 1", "stance": "regular", "style": "street" }, { "name": "Skater 2", "stance": "goofy", "style": "park" } ] }' # PATCH - Bulk update skaters curl -X PATCH http://localhost:3000/api/skaters \ -H "Content-Type: application/json" \ -d '{ "updates": [ { "id": "skater_123", "changes": { "status": "pro", "isPro": true } }, { "id": "skater_456", "changes": { "style": "vert" } } ] }' # DELETE - Bulk delete skaters curl -X DELETE http://localhost:3000/api/skaters \ -H "Content-Type: application/json" \ -d '{ "ids": ["skater_123", "skater_456"] }' ``` -------------------------------- ### Server-Side Queries with Drizzle ORM Source: https://context7.com/sadmann7/shadcn-table/llms.txt Demonstrates server-side pagination, sorting, and filtering using Drizzle ORM and Next.js caching. ```APIDOC ## GET /tasks ### Description Fetches tasks with support for pagination, sorting, and filtering. ### Method GET ### Endpoint /tasks ### Query Parameters - **page** (number) - Required - The current page number. - **perPage** (number) - Required - The number of tasks per page. - **sort** (array) - Optional - An array of sorting criteria. Each item should have an `id` (string) and `desc` (boolean). - **title** (string) - Optional - Filters tasks by title (case-insensitive). - **status** (array) - Optional - Filters tasks by status. - **priority** (array) - Optional - Filters tasks by priority. ### Response #### Success Response (200) - **data** (array) - An array of task objects. - **pageCount** (number) - The total number of pages available. #### Response Example ```json { "data": [ { "id": "some-task-id", "title": "Example Task", "status": "open", "label": "bug", "priority": "high", "createdAt": "2023-10-27T10:00:00Z" } ], "pageCount": 5 } ``` ``` -------------------------------- ### Server-Side Queries with Drizzle ORM and Next.js Cache Source: https://context7.com/sadmann7/shadcn-table/llms.txt Demonstrates server-side pagination, sorting, and filtering of tasks using Drizzle ORM. It leverages Next.js caching for improved performance by setting cache life and tags. ```typescript "use cache"; import "server-only"; import { and, asc, count, desc, gte, ilike, inArray, lte } from "drizzle-orm"; import { cacheLife, cacheTag } from "next/cache"; import { db } from "@/db"; import { tasks } from "@/db/schema"; import { filterColumns } from "@/lib/filter-columns"; import type { GetTasksSchema } from "./validations"; export async function getTasks(input: GetTasksSchema) { cacheLife({ revalidate: 1, stale: 1, expire: 60 }); cacheTag("tasks"); const offset = (input.page - 1) * input.perPage; const where = and( input.title ? ilike(tasks.title, `%${input.title}%`) : undefined, input.status.length > 0 ? inArray(tasks.status, input.status) : undefined, input.priority.length > 0 ? inArray(tasks.priority, input.priority) : undefined, ); const orderBy = input.sort.length > 0 ? input.sort.map((item) => (item.desc ? desc(tasks[item.id]) : asc(tasks[item.id]))) : [asc(tasks.createdAt)]; const { data, total } = await db.transaction(async (tx) => { const data = await tx .select() .from(tasks) .limit(input.perPage) .offset(offset) .where(where) .orderBy(...orderBy); const total = await tx .select({ count: count() }) .from(tasks) .where(where) .then((res) => res[0]?.count ?? 0); return { data, total }; }); return { data, pageCount: Math.ceil(total / input.perPage) }; } ``` -------------------------------- ### REST API for Skaters Source: https://context7.com/sadmann7/shadcn-table/llms.txt Provides CRUD operations for skaters with Zod validation and rate limiting. ```APIDOC ## GET /api/skaters ### Description Fetches all skaters. ### Method GET ### Endpoint /api/skaters ### Response #### Success Response (200) - **skaters** (array) - An array of skater objects. #### Response Example ```json [ { "id": "skater_123", "name": "Tony Hawk", "email": "tony@hawk.com", "stance": "goofy", "style": "vert", "status": "legend", "yearsSkating": 40, "isPro": true } ] ``` ``` ```APIDOC ## POST /api/skaters ### Description Creates a skater. Can be used for single or bulk creation. ### Method POST ### Endpoint /api/skaters ### Request Body - **skaters** (array) - Optional - An array of skater objects for bulk creation. Each object should have at least `name`, `stance`, and `style`. - **name** (string) - Required if not using `skaters` array - The name of the skater. - **email** (string) - Optional - The email of the skater. - **stance** (string) - Required if not using `skaters` array - The skating stance (e.g., 'regular', 'goofy'). - **style** (string) - Required if not using `skaters` array - The skating style (e.g., 'street', 'vert', 'park'). - **status** (string) - Optional - The status of the skater. - **yearsSkating** (number) - Optional - The number of years the skater has been skating. - **isPro** (boolean) - Optional - Whether the skater is a professional. ### Response #### Success Response (200) - **message** (string) - Confirmation message. #### Response Example ```json { "message": "Skater created successfully." } ``` ``` ```APIDOC ## PATCH /api/skaters ### Description Performs bulk updates on skaters. ### Method PATCH ### Endpoint /api/skaters ### Request Body - **updates** (array) - Required - An array of update objects. Each object must contain an `id` (string) and a `changes` object with the fields to update. - **id** (string) - Required - The ID of the skater to update. - **changes** (object) - Required - An object containing the fields to update (e.g., `status`, `isPro`, `style`). ### Response #### Success Response (200) - **message** (string) - Confirmation message. #### Response Example ```json { "message": "Skaters updated successfully." } ``` ``` ```APIDOC ## DELETE /api/skaters ### Description Performs bulk deletion of skaters. ### Method DELETE ### Endpoint /api/skaters ### Request Body - **ids** (array) - Required - An array of skater IDs to delete. ### Response #### Success Response (200) - **message** (string) - Confirmation message. #### Response Example ```json { "message": "Skaters deleted successfully." } ``` ``` -------------------------------- ### Drizzle ORM PostgreSQL Schema for Tasks Source: https://context7.com/sadmann7/shadcn-table/llms.txt Defines the 'tasks' table schema using Drizzle ORM for PostgreSQL. It includes fields for task management with various data types, constraints, and default values. ```tsx import { sql } from "drizzle-orm"; import { boolean, integer, real, timestamp, varchar } from "drizzle-orm/pg-core"; import { pgTable } from "@/db/utils"; export const tasks = pgTable("tasks", { id: varchar("id", { length: 30 }).$defaultFn(() => generateId()).primaryKey(), code: varchar("code", { length: 128 }).notNull().unique(), title: varchar("title", { length: 128 }), status: varchar("status", { length: 30, enum: ["todo", "in-progress", "done", "canceled"], }).notNull().default("todo"), priority: varchar("priority", { length: 30, enum: ["low", "medium", "high"], }).notNull().default("low"), label: varchar("label", { length: 30, enum: ["bug", "feature", "enhancement", "documentation"], }).notNull().default("bug"), estimatedHours: real("estimated_hours").notNull().default(0), archived: boolean("archived").notNull().default(false), createdAt: timestamp("created_at").defaultNow().notNull(), updatedAt: timestamp("updated_at") .default(sql`current_timestamp`) .$onUpdate(() => new Date()), }); export type Task = typeof tasks.$inferSelect; export type NewTask = typeof tasks.$inferInsert; ``` -------------------------------- ### Server Actions for CRUD Operations Source: https://context7.com/sadmann7/shadcn-table/llms.txt Provides type-safe mutations for creating, updating, and deleting tasks with cache invalidation. ```APIDOC ## POST /tasks (Create Task) ### Description Creates a new task. ### Method POST ### Endpoint /tasks ### Request Body - **title** (string) - Required - The title of the task. - **status** (string) - Required - The status of the task. - **label** (string) - Required - The label for the task. - **priority** (string) - Required - The priority of the task. ### Response #### Success Response (200) - **data** (null) - Indicates success. - **error** (null) - Indicates no error. #### Response Example ```json { "data": null, "error": null } ``` ``` ```APIDOC ## PUT /tasks/{id} (Update Task) ### Description Updates an existing task. ### Method PUT ### Endpoint /tasks/{id} ### Path Parameters - **id** (string) - Required - The ID of the task to update. ### Request Body - **title** (string) - Optional - The new title of the task. - **status** (string) - Optional - The new status of the task. - **priority** (string) - Optional - The new priority of the task. ### Response #### Success Response (200) - **data** (null) - Indicates success. - **error** (null) - Indicates no error. #### Response Example ```json { "data": null, "error": null } ``` ``` ```APIDOC ## DELETE /tasks (Delete Tasks) ### Description Deletes one or more tasks. ### Method DELETE ### Endpoint /tasks ### Request Body - **ids** (array) - Required - An array of task IDs to delete. ### Response #### Success Response (200) - **data** (null) - Indicates success. - **error** (null) - Indicates no error. #### Response Example ```json { "data": null, "error": null } ``` ``` -------------------------------- ### Server Actions for CRUD Operations with Next.js Cache Invalidation Source: https://context7.com/sadmann7/shadcn-table/llms.txt Implements server actions for creating, updating, and deleting tasks. It ensures type-safe mutations and utilizes Next.js `updateTag` for cache invalidation. ```typescript "use server"; import { eq, inArray } from "drizzle-orm"; import { updateTag } from "next/cache"; import { db } from "@/db/index"; import { tasks } from "@/db/schema"; import type { CreateTaskSchema, UpdateTaskSchema } from "./validations"; export async function createTask(input: CreateTaskSchema) { try { await db.insert(tasks).values({ code: `TASK-${Math.random().toString(36).slice(2, 6).toUpperCase()}`, title: input.title, status: input.status, label: input.label, priority: input.priority, }); updateTag("tasks"); updateTag("task-status-counts"); return { data: null, error: null }; } catch (err) { return { data: null, error: err instanceof Error ? err.message : "Unknown error" }; } } export async function updateTask(input: UpdateTaskSchema & { id: string }) { try { await db .update(tasks) .set({ title: input.title, status: input.status, priority: input.priority }) .where(eq(tasks.id, input.id)); updateTag("tasks"); return { data: null, error: null }; } catch (err) { return { data: null, error: err instanceof Error ? err.message : "Unknown error" }; } } export async function deleteTasks(input: { ids: string[] }) { try { await db.delete(tasks).where(inArray(tasks.id, input.ids)); updateTag("tasks"); updateTag("task-status-counts"); return { data: null, error: null }; } catch (err) { return { data: null, error: err instanceof Error ? err.message : "Unknown error" }; } } ``` -------------------------------- ### DataGrid - Editable Spreadsheet Component (React/TypeScript) Source: https://context7.com/sadmann7/shadcn-table/llms.txt Provides a spreadsheet-like editing experience with the `useDataGrid` hook. Features include cell selection, keyboard navigation, copy/paste, search, and undo/redo. It requires `@tanstack/react-table` and shadcn/ui components. ```tsx import { DataGrid } from "@/components/data-grid/data-grid"; import { useDataGrid } from "@/hooks/use-data-grid"; import type { ColumnDef } from "@tanstack/react-table"; import React from "react"; interface Skater { id: string; name: string | null; email: string | null; stance: "regular" | "goofy"; style: "street" | "vert" | "park"; status: "amateur" | "pro" | "legend"; yearsSkating: number; isPro: boolean; } const columns: ColumnDef[] = [ { id: "name", accessorKey: "name", header: "Name", meta: { label: "Name", cell: { variant: "short-text" }, }, }, { id: "stance", accessorKey: "stance", header: "Stance", meta: { label: "Stance", cell: { variant: "select", options: [ { label: "Regular", value: "regular" }, { label: "Goofy", value: "goofy" }, ], }, }, }, { id: "yearsSkating", accessorKey: "yearsSkating", header: "Years", meta: { label: "Years Skating", cell: { variant: "number", min: 0, max: 50 }, }, }, { id: "isPro", accessorKey: "isPro", header: "Pro", meta: { label: "Pro", cell: { variant: "checkbox" }, }, }, ]; export function SkaterGrid({ initialData }: { initialData: Skater[] }) { const [data, setData] = React.useState(initialData); const { table, tableMeta, ...dataGridProps } = useDataGrid({ data, columns, onDataChange: setData, onRowAdd: () => { const newSkater = { id: crypto.randomUUID(), name: null, email: null, stance: "regular", style: "street", status: "amateur", yearsSkating: 0, isPro: false }; setData((prev) => [...prev, newSkater]); return { rowIndex: data.length, columnId: "name" }; }, onRowsDelete: (rowsToDelete) => { setData((prev) => prev.filter((s) => !rowsToDelete.includes(s))); }, getRowId: (row) => row.id, enableSearch: true, enablePaste: true, }); return ; } ``` -------------------------------- ### DataTable - Server-Side Table with URL State Sync (React/TypeScript) Source: https://context7.com/sadmann7/shadcn-table/llms.txt Implements a server-side paginated table using the `useDataTable` hook. It synchronizes sorting, filtering, and column visibility state with URL query parameters. Dependencies include `@tanstack/react-table` and shadcn/ui components. ```tsx import { DataTable } from "@/components/data-table/data-table"; import { DataTableToolbar } from "@/components/data-table/data-table-toolbar"; import { DataTableSortList } from "@/components/data-table/data-table-sort-list"; import { useDataTable } from "@/hooks/use-data-table"; import type { ColumnDef } from "@tanstack/react-table"; interface Task { id: string; code: string; title: string; status: "todo" | "in-progress" | "done" | "canceled"; priority: "low" | "medium" | "high"; createdAt: Date; } const columns: ColumnDef[] = [ { accessorKey: "code", header: "Code", enableColumnFilter: false, }, { accessorKey: "title", header: "Title", enableColumnFilter: true, }, { id: "status", accessorKey: "status", header: "Status", enableColumnFilter: true, meta: { options: [ { label: "Todo", value: "todo" }, { label: "In Progress", value: "in-progress" }, { label: "Done", value: "done" }, ], }, }, ]; export function TasksTable({ data, pageCount }: { data: Task[]; pageCount: number }) { const { table } = useDataTable({ data, columns, pageCount, initialState: { sorting: [{ id: "createdAt", desc: true }], columnPinning: { right: ["actions"] }, }, getRowId: (row) => row.id, shallow: false, clearOnDefault: true, }); return ( ); } ``` -------------------------------- ### Zod Validation Schemas for Skater Data Source: https://context7.com/sadmann7/shadcn-table/llms.txt Provides Zod schemas for validating skater data, including schemas for single and bulk inserts, updates, and deletes. These schemas ensure type safety for API requests and form handling. ```tsx import { z } from "zod"; import { skaters } from "@/db/schema"; // Insert schema - all fields optional except required ones export const insertSkaterSchema = z.object({ id: z.string().optional(), name: z.string().nullable().optional(), email: z.string().email().nullable().optional(), stance: z.enum(skaters.stance.enumValues).optional(), style: z.enum(skaters.style.enumValues).optional(), status: z.enum(skaters.status.enumValues).optional(), yearsSkating: z.number().min(0).optional(), startedSkating: z.coerce.date().nullable().optional(), isPro: z.boolean().optional(), }); // Bulk insert schema export const insertSkatersSchema = z.object({ skaters: z.array(insertSkaterSchema).min(1), }); // Update schema - all fields optional export const updateSkaterSchema = z.object({ name: z.string().nullable().optional(), stance: z.enum(skaters.stance.enumValues).optional(), status: z.enum(skaters.status.enumValues).optional(), yearsSkating: z.number().optional(), isPro: z.boolean().optional(), }); // Bulk update schema export const updateSkatersSchema = z.object({ updates: z.array(z.object({ id: z.string(), changes: updateSkaterSchema, })).min(1), }); // Delete schema export const deleteSkatersSchema = z.object({ ids: z.array(z.string()).min(1), }); ``` -------------------------------- ### Generate Drizzle SQL Conditions with filterColumns Source: https://context7.com/sadmann7/shadcn-table/llms.txt The filterColumns utility generates Drizzle SQL conditions from filter specifications, supporting operators like iLike, eq, inArray, isBetween, and date-relative filtering. It takes a table schema, an array of filter configurations, and a join operator ('and' or 'or') as input, returning a Drizzle SQL WHERE clause. ```tsx import { filterColumns } from "@/lib/filter-columns"; import { tasks } from "@/db/schema"; import type { ExtendedColumnFilter } from "@/types/data-table"; const filters: ExtendedColumnFilter[] = [ { id: "title", value: "auth", operator: "iLike", variant: "text" }, { id: "status", value: ["todo", "in-progress"], operator: "inArray", variant: "multi-select" }, { id: "priority", value: "high", operator: "eq", variant: "select" }, { id: "estimatedHours", value: ["5", "20"], operator: "isBetween", variant: "range" }, { id: "createdAt", value: "-7 days", operator: "isRelativeToToday", variant: "date" }, ]; const where = filterColumns({ table: tasks, filters, joinOperator: "and", // or "or" }); // Use in query: // const results = await db.select().from(tasks).where(where); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.