summaryrefslogtreecommitdiff
path: root/components/client-table-v2/client-table-filter.tsx
diff options
context:
space:
mode:
authorjoonhoekim <26rote@gmail.com>2025-12-01 15:22:38 +0900
committerjoonhoekim <26rote@gmail.com>2025-12-01 15:22:38 +0900
commitffb8e2e99e1d0c105b1c545ff7ab4d3149ec6c48 (patch)
tree1af87b9c19bc56ed1192a5b5947d22fa5f4dbd98 /components/client-table-v2/client-table-filter.tsx
parentd674b066a9a3195d764f693885fb9f25d66263ed (diff)
(김준회) 서버측 where, order by 절 지원을 위한 v2 임시작업
Diffstat (limited to 'components/client-table-v2/client-table-filter.tsx')
-rw-r--r--components/client-table-v2/client-table-filter.tsx101
1 files changed, 101 insertions, 0 deletions
diff --git a/components/client-table-v2/client-table-filter.tsx b/components/client-table-v2/client-table-filter.tsx
new file mode 100644
index 00000000..138f77eb
--- /dev/null
+++ b/components/client-table-v2/client-table-filter.tsx
@@ -0,0 +1,101 @@
+"use client"
+
+import * as React from "react"
+import { Column } from "@tanstack/react-table"
+import { Input } from "@/components/ui/input"
+import {
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@/components/ui/select"
+import { ClientTableColumnMeta } from "./types"
+
+interface ClientTableFilterProps<TData, TValue> {
+ column: Column<TData, TValue>
+}
+
+export function ClientTableFilter<TData, TValue>({
+ column,
+}: ClientTableFilterProps<TData, TValue>) {
+ const columnFilterValue = column.getFilterValue()
+ // Cast meta to our local type
+ const meta = column.columnDef.meta as ClientTableColumnMeta | undefined
+
+ // Handle Boolean Filter
+ if (meta?.filterType === "boolean") {
+ return (
+ <div onClick={(e) => e.stopPropagation()} className="mt-2">
+ <Select
+ value={(columnFilterValue as string) ?? "all"}
+ onValueChange={(value) =>
+ column.setFilterValue(value === "all" ? undefined : value === "true")
+ }
+ >
+ <SelectTrigger className="h-8 w-full">
+ <SelectValue placeholder="All" />
+ </SelectTrigger>
+ <SelectContent>
+ <SelectItem value="all">All</SelectItem>
+ <SelectItem value="true">Yes</SelectItem>
+ <SelectItem value="false">No</SelectItem>
+ </SelectContent>
+ </Select>
+ </div>
+ )
+ }
+
+ // Handle Select Filter (for specific options)
+ if (meta?.filterType === "select" && meta.filterOptions) {
+ return (
+ <div onClick={(e) => e.stopPropagation()} className="mt-2">
+ <Select
+ value={(columnFilterValue as string) ?? "all"}
+ onValueChange={(value) =>
+ column.setFilterValue(value === "all" ? undefined : value)
+ }
+ >
+ <SelectTrigger className="h-8 w-full">
+ <SelectValue placeholder="All" />
+ </SelectTrigger>
+ <SelectContent>
+ <SelectItem value="all">All</SelectItem>
+ {meta.filterOptions.map((option) => (
+ <SelectItem key={option.value} value={option.value}>
+ {option.label}
+ </SelectItem>
+ ))}
+ </SelectContent>
+ </Select>
+ </div>
+ )
+ }
+
+ // Default Text Filter
+ const [value, setValue] = React.useState(columnFilterValue)
+
+ React.useEffect(() => {
+ setValue(columnFilterValue)
+ }, [columnFilterValue])
+
+ React.useEffect(() => {
+ const timeout = setTimeout(() => {
+ column.setFilterValue(value)
+ }, 500)
+
+ return () => clearTimeout(timeout)
+ }, [value, column])
+
+ return (
+ <div onClick={(e) => e.stopPropagation()} className="mt-2">
+ <Input
+ type="text"
+ value={(value ?? "") as string}
+ onChange={(e) => setValue(e.target.value)}
+ placeholder="Search..."
+ className="h-8 w-full font-normal bg-background"
+ />
+ </div>
+ )
+}