gbclient/app/tables/components/DataTableToolbar.tsx

94 lines
4.1 KiB
TypeScript
Raw Normal View History

import React, { useState } from 'react';
import { Task } from '../data/schema';
import { priorities, statuses } from '../data/data';
interface DataTableToolbarProps {
onFilter: (filteredData: Task[]) => void;
data: Task[];
}
export const DataTableToolbar: React.FC<DataTableToolbarProps> = ({ onFilter, data }) => {
const [searchText, setSearchText] = useState('');
const [statusFilter, setStatusFilter] = useState<string[]>([]);
const [priorityFilter, setPriorityFilter] = useState<string[]>([]);
const applyFilters = () => {
const filteredData = data.filter(task => {
const matchesSearch = task.title.toLowerCase().includes(searchText.toLowerCase());
const matchesStatus = statusFilter.length === 0 || statusFilter.includes(task.status);
const matchesPriority = priorityFilter.length === 0 || priorityFilter.includes(task.priority);
return matchesSearch && matchesStatus && matchesPriority;
});
onFilter(filteredData);
};
const toggleFilter = (filter: string[], value: string, setFilter: (filter: string[]) => void) => {
const newFilter = filter.includes(value)
? filter.filter(f => f !== value)
: [...filter, value];
setFilter(newFilter);
applyFilters();
};
return (
<div className="px-6 py-4 bg-white border-b border-gray-200">
<div className="flex items-center justify-between">
<div className="flex-1 max-w-lg">
<input
type="text"
placeholder="Filter tasks..."
className="block w-full px-4 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500"
value={searchText}
onChange={(e) => {
setSearchText(e.target.value);
applyFilters();
}}
/>
</div>
<div className="ml-4 flex space-x-4">
<div className="relative">
<button className="inline-flex justify-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Status
</button>
<div className="origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 z-10">
<div className="py-1">
{statuses.map((status) => (
<label key={status.value} className="flex items-center px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
<input
type="checkbox"
checked={statusFilter.includes(status.value)}
onChange={() => toggleFilter(statusFilter, status.value, setStatusFilter)}
className="mr-2"
/>
{status.label}
</label>
))}
</div>
</div>
</div>
<div className="relative">
<button className="inline-flex justify-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Priority
</button>
<div className="origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 z-10">
<div className="py-1">
{priorities.map((priority) => (
<label key={priority.value} className="flex items-center px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
<input
type="checkbox"
checked={priorityFilter.includes(priority.value)}
onChange={() => toggleFilter(priorityFilter, priority.value, setPriorityFilter)}
className="mr-2"
/>
{priority.label}
</label>
))}
</div>
</div>
</div>
</div>
</div>
</div>
);
};