[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:
[dyad] 2025-09-23 16:34:26 +02:00
parent 19ae6a9f6c
commit a7ef17d9bf
2 changed files with 36 additions and 45 deletions

View file

@ -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>

View file

@ -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>
)