From ffb8e2e99e1d0c105b1c545ff7ab4d3149ec6c48 Mon Sep 17 00:00:00 2001
From: joonhoekim <26rote@gmail.com>
Date: Mon, 1 Dec 2025 15:22:38 +0900
Subject: (김준회) 서버측 where, order by 절 지원을 위한 v2 임시작업
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 components/client-table-v2/client-table-filter.tsx | 101 +++++++++++++++++++++
 1 file changed, 101 insertions(+)
 create mode 100644 components/client-table-v2/client-table-filter.tsx

(limited to 'components/client-table-v2/client-table-filter.tsx')

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>
+  )
+}
-- 
cgit v1.2.3

