"use client" import * as React from "react" import { cn } from "@/lib/utils" import { ArrowDown, ArrowUp, ArrowUpDown, Filter } from "lucide-react" import { Input } from "./input" import { Button } from "./button" import { Skeleton } from "./skeleton" import { AsyncCombobox, Option } from "./combobox" import { DatePicker } from "./date-picker" function Table({ className, ...props }: React.ComponentProps<"table">) { return (
) } function TableHeader({ className, ...props }: React.ComponentProps<"thead">) { return ( ) } function TableBody({ className, ...props }: React.ComponentProps<"tbody">) { return ( ) } function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) { return ( tr]:last:border-b-0", className )} {...props} /> ) } function TableRow({ className, ...props }: React.ComponentProps<"tr">) { return ( ) } function TableHead({ className, ...props }: React.ComponentProps<"th">) { return (
) } function TableCell({ className, ...props }: React.ComponentProps<"td">) { return ( ) } function TableCaption({ className, ...props }: React.ComponentProps<"caption">) { return (
) } // eslint-disable-next-line @typescript-eslint/no-explicit-any function SortableHeader({ column, title }: { column: any; title: string }) { return ( ) } function FilterInput({ value, onChange, placeholder, }: { value: string onChange: (value: string) => void placeholder?: string }) { return ( onChange(e.target.value)} placeholder={placeholder} className="h-8 text-xs" type="search" /> ) } interface SFCHPBase { // eslint-disable-next-line @typescript-eslint/no-explicit-any column: any title: string placeholder?: string } interface DefaultColumn extends SFCHPBase { type: "default" } interface WithOptions extends SFCHPBase { type: "select" get_options: (query: string, page: number) => Promise } interface Dates extends SFCHPBase { type: "date" from: boolean to: boolean } export function createColumn>( config: T ): T extends { get_options: (query: string, page: number) => Promise } ? WithOptions : T extends { from: boolean; to: boolean } ? Dates : DefaultColumn { if ("get_options" in config) { // eslint-disable-next-line @typescript-eslint/no-explicit-any return { ...config, type: "select" } as any } if ("from" in config || "to" in config) { // eslint-disable-next-line @typescript-eslint/no-explicit-any return { ...config, type: "date" } as any } // eslint-disable-next-line @typescript-eslint/no-explicit-any return { ...config, type: "default" } as any } type SFCHP = DefaultColumn | WithOptions | Dates function SortableFilterableColumnHeader(props: SFCHP) { const { column, title, placeholder, type } = props const get_options = type === "select" ? props.get_options : undefined const { from, to } = type === "date" ? props : {} const [showFilter, setShowFilter] = React.useState(false) const canSort = column.getCanSort() const canFilter = column.getCanFilter() function getDateFilterInput() { if (type !== "date") return null if (from && to) return ( !dates ? column.setFilterValue(undefined) : column.setFilterValue({ ...dates, to: dates?.to ? new Date(dates.to.setHours(23, 59, 59, 0)) : undefined, }) } range /> ) if (from) return ( <> {" "} - column.setFilterValue({ from: date })} /> ) if (to) return ( <> column.setFilterValue({ to: date ? new Date(date.setHours(23, 59, 59, 0)) : undefined, }) } />{" "} - ) return null } function getFilterInput() { switch (type) { case "select": return ( column.setFilterValue(value)} /> ) case "date": return getDateFilterInput() case "default": default: return ( column.setFilterValue(value)} placeholder={placeholder} /> ) } } return (
{canSort && } {!canSort && {title}} {canFilter && ( )}
{canFilter && showFilter ? getFilterInput() : null}
) } interface TableSkeletonProps { columns: number rows?: number } function TableRowSkeleton({ columns, rows = 5 }: TableSkeletonProps) { return Array.from({ length: rows }).map((_, rowIndex) => ( {Array.from({ length: columns }).map((_, colIndex) => ( ))} )) } export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption, SortableHeader, FilterInput, SortableFilterableColumnHeader, TableRowSkeleton, }