[dyad] Enhanced stock search to filter by partial name, SKU, and category - wrote 2 file(s) + extra files edited outside of Dyad
This commit is contained in:
parent
19ae6a9f6c
commit
a7ef17d9bf
2 changed files with 36 additions and 45 deletions
|
|
@ -13,8 +13,8 @@ import {
|
|||
getSortedRowModel,
|
||||
useReactTable,
|
||||
} from "@tanstack/react-table"
|
||||
import { Columns } from "lucide-react"
|
||||
|
||||
import { Input } from "@/components/ui/input"
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
|
|
@ -24,42 +24,28 @@ import {
|
|||
TableRow,
|
||||
} from "@/components/ui/table"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuCheckboxItem,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu"
|
||||
import { Columns } from "lucide-react"
|
||||
|
||||
interface DataTableProps<TData, TValue> {
|
||||
columns: ColumnDef<TData, TValue>[]
|
||||
data: TData[]
|
||||
filterValue: string
|
||||
onFilterChange: (value: string) => void
|
||||
}
|
||||
|
||||
export function DataTable<TData, TValue>({
|
||||
columns,
|
||||
data,
|
||||
filterValue,
|
||||
onFilterChange,
|
||||
}: DataTableProps<TData, TValue>) {
|
||||
const [sorting, setSorting] = React.useState<SortingState>([])
|
||||
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>([])
|
||||
const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>(() => {
|
||||
if (typeof window !== 'undefined' && window.innerWidth < 768) {
|
||||
return {
|
||||
sku: false,
|
||||
quantity: false,
|
||||
status: false,
|
||||
actions: false,
|
||||
costPrice: false,
|
||||
};
|
||||
}
|
||||
return {};
|
||||
});
|
||||
const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>({})
|
||||
const [rowSelection, setRowSelection] = React.useState({})
|
||||
const [globalFilter, setGlobalFilter] = React.useState("") // Global filter state
|
||||
|
||||
const table = useReactTable({
|
||||
data,
|
||||
|
|
@ -72,31 +58,41 @@ export function DataTable<TData, TValue>({
|
|||
getFilteredRowModel: getFilteredRowModel(),
|
||||
onColumnVisibilityChange: setColumnVisibility,
|
||||
onRowSelectionChange: setRowSelection,
|
||||
onGlobalFilterChange: setGlobalFilter,
|
||||
state: {
|
||||
sorting,
|
||||
columnFilters,
|
||||
columnVisibility,
|
||||
rowSelection,
|
||||
globalFilter, // Enable global filtering
|
||||
},
|
||||
globalFilterFn: (row, columnId, filterValue) => {
|
||||
// Custom global filter function to search across name, sku, and category
|
||||
const searchValue = filterValue.toLowerCase();
|
||||
const rowValue = row.getValue("name")?.toString().toLowerCase() || "";
|
||||
const skuValue = row.getValue("sku")?.toString().toLowerCase() || "";
|
||||
const categoryValue = row.getValue("category")?.toString().toLowerCase() || "";
|
||||
|
||||
return (
|
||||
rowValue.includes(searchValue) ||
|
||||
skuValue.includes(searchValue) ||
|
||||
categoryValue.includes(searchValue)
|
||||
);
|
||||
},
|
||||
})
|
||||
|
||||
// Sync external filter value with the table's internal state
|
||||
React.useEffect(() => {
|
||||
table.getColumn("sku")?.setFilterValue(filterValue)
|
||||
}, [filterValue, table])
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center py-4">
|
||||
<Input
|
||||
placeholder="Filter by SKU..."
|
||||
value={filterValue}
|
||||
onChange={(event) => onFilterChange(event.target.value)}
|
||||
placeholder="Search by name, SKU, or category..."
|
||||
value={globalFilter ?? ""}
|
||||
onChange={(event) => table.setGlobalFilter(event.target.value)}
|
||||
className="max-w-sm"
|
||||
/>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="outline" size="icon" className="ml-auto">
|
||||
<Button variant="outline" size="sm" className="ml-auto h-9 px-3">
|
||||
<Columns className="h-4 w-4" />
|
||||
<span className="sr-only">Toggle columns</span>
|
||||
</Button>
|
||||
|
|
@ -124,23 +120,21 @@ export function DataTable<TData, TValue>({
|
|||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
<div className="rounded-md border bg-white">
|
||||
<div className="rounded-md border">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<TableRow key={headerGroup.id}>
|
||||
{headerGroup.headers.map((header) => {
|
||||
return (
|
||||
<TableHead key={header.id}>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext()
|
||||
)}
|
||||
</TableHead>
|
||||
)
|
||||
})}
|
||||
{headerGroup.headers.map((header) => (
|
||||
<TableHead key={header.id}>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext()
|
||||
)}
|
||||
</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableHeader>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useState, useEffect, useCallback } from "react"
|
||||
import { createColumns, StockItem } from "../components/stock/columns" // Changed from 'columns' to 'createColumns'
|
||||
import { createColumns, StockItem } from "../components/stock/columns"
|
||||
import { DataTable } from "../components/stock/data-table"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { PlusCircle } from "lucide-react"
|
||||
|
|
@ -19,7 +19,6 @@ const Stock = () => {
|
|||
const [addItemOpen, setAddItemOpen] = useState(false);
|
||||
const [stockItems, setStockItems] = useState<StockItem[]>([]);
|
||||
const [refreshTrigger, setRefreshTrigger] = useState(0); // State to trigger data refresh
|
||||
const [filterValue, setFilterValue] = useState(""); // State for filtering
|
||||
|
||||
const fetchStockItems = useCallback(async () => {
|
||||
try {
|
||||
|
|
@ -81,8 +80,6 @@ const Stock = () => {
|
|||
<DataTable
|
||||
columns={columns}
|
||||
data={stockItems}
|
||||
filterValue={filterValue} // Pass filterValue
|
||||
onFilterChange={setFilterValue} // Pass onFilterChange
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue