history
This commit is contained in:
@@ -66,6 +66,20 @@ const History = () => {
|
|||||||
fetchHistoryData();
|
fetchHistoryData();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// Close dropdown when clicking outside
|
||||||
|
useEffect(() => {
|
||||||
|
const handleClickOutside = (event) => {
|
||||||
|
if (showProductDropdown && !event.target.closest('.relative')) {
|
||||||
|
setShowProductDropdown(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('mousedown', handleClickOutside);
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('mousedown', handleClickOutside);
|
||||||
|
};
|
||||||
|
}, [showProductDropdown]);
|
||||||
|
|
||||||
const fetchHistoryData = async () => {
|
const fetchHistoryData = async () => {
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
@@ -248,7 +262,7 @@ const History = () => {
|
|||||||
|
|
||||||
{showFilters && (
|
{showFilters && (
|
||||||
<div className="p-4">
|
<div className="p-4">
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5 gap-4">
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6 gap-4">
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
Time Period
|
Time Period
|
||||||
@@ -262,7 +276,32 @@ const History = () => {
|
|||||||
<option value="today">Today</option>
|
<option value="today">Today</option>
|
||||||
<option value="week">Last Week</option>
|
<option value="week">Last Week</option>
|
||||||
<option value="month">Last Month</option>
|
<option value="month">Last Month</option>
|
||||||
|
<option value="custom">Custom Range</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
{/* Date Range Inputs */}
|
||||||
|
{dateFilter === 'custom' && (
|
||||||
|
<div className="mt-2 grid grid-cols-2 gap-2">
|
||||||
|
<div>
|
||||||
|
<label className="block text-xs text-gray-600 mb-1">From</label>
|
||||||
|
<input
|
||||||
|
type="date"
|
||||||
|
value={dateRangeStart}
|
||||||
|
onChange={(e) => setDateRangeStart(e.target.value)}
|
||||||
|
className="w-full border border-gray-300 rounded px-2 py-1 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="block text-xs text-gray-600 mb-1">To</label>
|
||||||
|
<input
|
||||||
|
type="date"
|
||||||
|
value={dateRangeEnd}
|
||||||
|
onChange={(e) => setDateRangeEnd(e.target.value)}
|
||||||
|
className="w-full border border-gray-300 rounded px-2 py-1 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
@@ -298,17 +337,80 @@ const History = () => {
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
Product
|
Products
|
||||||
|
</label>
|
||||||
|
<div className="relative">
|
||||||
|
<button
|
||||||
|
onClick={() => setShowProductDropdown(!showProductDropdown)}
|
||||||
|
className="w-full border border-gray-300 rounded px-3 py-2 text-sm text-left focus:outline-none focus:ring-2 focus:ring-blue-500 flex items-center justify-between"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
{selectedProducts.length === 0
|
||||||
|
? 'All Products'
|
||||||
|
: `${selectedProducts.length} selected`
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
<svg className={`h-4 w-4 transform transition-transform ${showProductDropdown ? 'rotate-180' : ''}`} fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{showProductDropdown && (
|
||||||
|
<div className="absolute z-10 w-full mt-1 bg-white border border-gray-300 rounded-md shadow-lg max-h-60 overflow-auto">
|
||||||
|
{uniqueProducts.length === 0 ? (
|
||||||
|
<div className="px-3 py-2 text-sm text-gray-500">No products available</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<div className="px-3 py-2 border-b">
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
if (selectedProducts.length === uniqueProducts.length) {
|
||||||
|
setSelectedProducts([]);
|
||||||
|
} else {
|
||||||
|
setSelectedProducts([...uniqueProducts]);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
className="text-xs text-blue-600 hover:text-blue-800"
|
||||||
|
>
|
||||||
|
{selectedProducts.length === uniqueProducts.length ? 'Deselect All' : 'Select All'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{uniqueProducts.map(product => (
|
||||||
|
<label key={product} className="flex items-center px-3 py-2 hover:bg-gray-50 cursor-pointer">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={selectedProducts.includes(product)}
|
||||||
|
onChange={(e) => {
|
||||||
|
if (e.target.checked) {
|
||||||
|
setSelectedProducts([...selectedProducts, product]);
|
||||||
|
} else {
|
||||||
|
setSelectedProducts(selectedProducts.filter(p => p !== product));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
className="mr-2"
|
||||||
|
/>
|
||||||
|
<span className="text-sm">{product}</span>
|
||||||
|
</label>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
|
Application Type
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
value={productFilter}
|
value={applicationTypeFilter}
|
||||||
onChange={(e) => setProductFilter(e.target.value)}
|
onChange={(e) => setApplicationTypeFilter(e.target.value)}
|
||||||
className="w-full border border-gray-300 rounded px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
|
className="w-full border border-gray-300 rounded px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
>
|
>
|
||||||
<option value="all">All Products</option>
|
<option value="all">All Types</option>
|
||||||
{uniqueProducts.map(product => (
|
<option value="granular">Granular</option>
|
||||||
<option key={product} value={product}>{product}</option>
|
<option value="liquid">Liquid</option>
|
||||||
))}
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -332,10 +434,14 @@ const History = () => {
|
|||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setDateFilter('all');
|
setDateFilter('all');
|
||||||
|
setDateRangeStart('');
|
||||||
|
setDateRangeEnd('');
|
||||||
setStatusFilter('all');
|
setStatusFilter('all');
|
||||||
setPropertyFilter('all');
|
setPropertyFilter('all');
|
||||||
setProductFilter('all');
|
setSelectedProducts([]);
|
||||||
|
setApplicationTypeFilter('all');
|
||||||
setSortBy('date');
|
setSortBy('date');
|
||||||
|
setShowProductDropdown(false);
|
||||||
}}
|
}}
|
||||||
className="px-4 py-2 text-sm text-gray-600 hover:text-gray-800 border border-gray-300 rounded hover:bg-gray-50"
|
className="px-4 py-2 text-sm text-gray-600 hover:text-gray-800 border border-gray-300 rounded hover:bg-gray-50"
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user