import { useState, useEffect } from "react";
import { createColumnHelper } from "@tanstack/react-table";
import { format } from "date-fns";
import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select";
import { Search } from "lucide-react";
export const pageSizes = [10, 25, 50, 75, 100, 250, 500, 750, 1000]
// ── Badge style map for enum values ───────────────────────────────────────────
export const BADGE_STYLES = {
"Active": "bg-emerald-100 text-emerald-800 border-emerald-200",
"Not Active": "bg-rose-100 text-rose-700 border-rose-200",
"Verified": "bg-blue-100 text-blue-800 border-blue-200",
"Not Verified": "bg-amber-100 text-amber-700 border-amber-200",
"system": "bg-violet-50 text-violet-700 border-violet-200",
"google": "bg-orange-50 text-orange-700 border-orange-200",
"admin": "bg-red-100 text-red-700 border-red-200",
"user": "bg-blue-100 text-blue-700 border-blue-200",
"staff": "bg-green-100 text-green-700 border-green-200",
};
function EnumBadge({ value }) {
return (
{value}
);
}
export function formatDate(value) {
if (!value) return null;
try { return format(new Date(value), "MMM d, yyyy"); }
catch { return value; }
}
function renderCell(attr, value) {
if (value === null || value === undefined || value === "") {
return -;
}
switch (attr.type) {
case "enum":
if (attr.field === "is_active")
return ;
else if (attr.field === "is_verified")
return ;
else
return ;
case "date": return {formatDate(value)};
case "number": return {value};
default: return {value};
}
}
export function ColumnFilter({ column, attr }) {
const columnValue = column.getFilterValue() ?? "";
const [inputValue, setInputValue] = useState(columnValue);
// keep in sync when external reset happens
useEffect(() => {
setInputValue(columnValue);
}, [columnValue]);
// ─────────────────────────────────────────────
// ENUM (AUTO APPLY)
// ─────────────────────────────────────────────
if (attr.type === "enum") {
return (
);
}
// ─────────────────────────────────────────────
// DATE (SINGLE)
// ─────────────────────────────────────────────
if (attr.type === "date") {
const value =
inputValue &&
typeof inputValue === "object" &&
("from" in inputValue || "to" in inputValue)
? inputValue
: null;
const isRange = !!value;
return (
);
}
// ─────────────────────────────────────────────
// TEXT FILTER (manual apply)
// ─────────────────────────────────────────────
return (
setInputValue(e.target.value)}
onKeyDown={(e) => {
if (e.key === "Enter") {
column.setFilterValue(inputValue);
}
}}
placeholder="Filter..."
className="h-7 text-xs w-full"
/>
);
}
// ── Sort icon ──────────────────────────────────────────────────────────────────
export function SortIcon({ column }) {
const s = column.getIsSorted();
if (s === "asc") return ;
if (s === "desc") return ;
return ;
}
// ── Build columns dynamically from attributes ──────────────────────────────────
const columnHelper = createColumnHelper();
export function buildColumns(attributes, { cellOverrides = {} } = {}) {
return attributes.map((attr) =>
columnHelper.accessor(attr.field, {
id: attr.field,
header: attr.name,
enableSorting: true,
enableColumnFilter: true,
filterFn: (row, colId, filterValue) => {
if (!filterValue) return true;
const val = String(row.getValue(colId) ?? "").toLowerCase();
return val.includes(String(filterValue).toLowerCase());
},
cell: (info) =>
cellOverrides[attr.field] // ← check override first
? cellOverrides[attr.field](info)
: renderCell(attr, info.getValue()),
meta: { attr },
})
);
}