This commit is contained in:
Jake Kasper
2025-08-28 08:27:55 -05:00
parent 5606bb18c9
commit 0aef10f69c

View File

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