puffin-app/components/admin/OrderFilters.tsx

199 lines
8.2 KiB
TypeScript
Raw Normal View History

'use client';
import { useState } from 'react';
import { Search, Filter, X, Calendar } from 'lucide-react';
interface OrderFiltersProps {
onSearchChange: (search: string) => void;
onStatusChange: (status: string) => void;
onDateRangeChange: (dateFrom: string, dateTo: string) => void;
onReset: () => void;
searchValue: string;
statusValue: string;
dateFromValue: string;
dateToValue: string;
}
export function OrderFilters({
onSearchChange,
onStatusChange,
onDateRangeChange,
searchValue,
statusValue,
dateFromValue,
dateToValue,
onReset,
}: OrderFiltersProps) {
const [showDatePicker, setShowDatePicker] = useState(false);
const [localDateFrom, setLocalDateFrom] = useState(dateFromValue);
const [localDateTo, setLocalDateTo] = useState(dateToValue);
const handleApplyDateRange = () => {
onDateRangeChange(localDateFrom, localDateTo);
setShowDatePicker(false);
};
const handleResetDateRange = () => {
setLocalDateFrom('');
setLocalDateTo('');
onDateRangeChange('', '');
setShowDatePicker(false);
};
const hasActiveFilters = searchValue || statusValue || dateFromValue || dateToValue;
return (
<div className="bg-white border border-light-gray-border rounded-xl p-6 mb-6">
<div className="flex flex-col lg:flex-row gap-4">
{/* Search Input */}
<div className="flex-1 relative">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-deep-sea-blue/40" />
<input
type="text"
placeholder="Search by order ID, customer name, or email..."
value={searchValue}
onChange={(e) => onSearchChange(e.target.value)}
className="w-full pl-11 pr-4 py-2.5 border border-light-gray-border rounded-lg bg-white text-deep-sea-blue placeholder-deep-sea-blue/40 focus:outline-none focus:ring-2 focus:ring-deep-sea-blue/20 focus:border-deep-sea-blue transition-all"
/>
</div>
{/* Status Filter */}
<div className="relative">
<Filter className="absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-deep-sea-blue/40" />
<select
value={statusValue}
onChange={(e) => onStatusChange(e.target.value)}
className="pl-10 pr-10 py-2.5 border border-light-gray-border rounded-lg bg-white text-deep-sea-blue focus:outline-none focus:ring-2 focus:ring-deep-sea-blue/20 focus:border-deep-sea-blue transition-all cursor-pointer appearance-none"
style={{ minWidth: '160px' }}
>
<option value="">All Status</option>
<option value="pending">Pending</option>
<option value="paid">Paid</option>
<option value="fulfilled">Fulfilled</option>
<option value="cancelled">Cancelled</option>
</select>
<div className="absolute right-3 top-1/2 transform -translate-y-1/2 pointer-events-none">
<svg className="w-4 h-4 text-deep-sea-blue/40" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
</svg>
</div>
</div>
{/* Date Range Picker */}
<div className="relative">
<button
type="button"
onClick={() => setShowDatePicker(!showDatePicker)}
className="flex items-center space-x-2 px-4 py-2.5 border border-light-gray-border rounded-lg bg-white text-deep-sea-blue hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-deep-sea-blue/20 transition-all"
>
<Calendar className="w-4 h-4" />
<span className="text-sm font-medium">
{dateFromValue && dateToValue ? 'Date Range' : 'All Dates'}
</span>
{(dateFromValue || dateToValue) && (
<span className="px-2 py-0.5 text-xs bg-deep-sea-blue text-white rounded-full">1</span>
)}
</button>
{/* Date Picker Dropdown */}
{showDatePicker && (
<div className="absolute right-0 mt-2 p-4 bg-white border border-light-gray-border rounded-xl shadow-lg z-10 min-w-[300px]">
<div className="space-y-4">
<div>
<label className="block text-sm font-medium text-deep-sea-blue mb-2">From Date</label>
<input
type="date"
value={localDateFrom}
onChange={(e) => setLocalDateFrom(e.target.value)}
className="w-full px-3 py-2 border border-light-gray-border rounded-lg focus:outline-none focus:ring-2 focus:ring-deep-sea-blue/20"
/>
</div>
<div>
<label className="block text-sm font-medium text-deep-sea-blue mb-2">To Date</label>
<input
type="date"
value={localDateTo}
onChange={(e) => setLocalDateTo(e.target.value)}
className="w-full px-3 py-2 border border-light-gray-border rounded-lg focus:outline-none focus:ring-2 focus:ring-deep-sea-blue/20"
/>
</div>
<div className="flex space-x-2 pt-2">
<button
type="button"
onClick={handleResetDateRange}
className="flex-1 px-4 py-2 text-sm font-medium text-deep-sea-blue bg-gray-100 hover:bg-gray-200 rounded-lg transition-colors"
>
Clear
</button>
<button
type="button"
onClick={handleApplyDateRange}
className="flex-1 px-4 py-2 text-sm font-medium text-white bg-deep-sea-blue hover:bg-deep-sea-blue/90 rounded-lg transition-colors"
>
Apply
</button>
</div>
</div>
</div>
)}
</div>
{/* Reset Filters Button */}
{hasActiveFilters && (
<button
type="button"
onClick={onReset}
className="flex items-center space-x-2 px-4 py-2.5 text-sm font-medium text-red-600 bg-red-50 hover:bg-red-100 border border-red-200 rounded-lg transition-colors"
>
<X className="w-4 h-4" />
<span>Reset</span>
</button>
)}
</div>
{/* Active Filters Display */}
{hasActiveFilters && (
<div className="flex flex-wrap items-center gap-2 mt-4 pt-4 border-t border-light-gray-border">
<span className="text-sm font-medium text-deep-sea-blue/70">Active filters:</span>
{searchValue && (
<span className="inline-flex items-center px-3 py-1 text-xs font-medium bg-deep-sea-blue/10 text-deep-sea-blue rounded-full">
Search: "{searchValue}"
<button
type="button"
onClick={() => onSearchChange('')}
className="ml-2 hover:text-deep-sea-blue/70"
>
<X className="w-3 h-3" />
</button>
</span>
)}
{statusValue && (
<span className="inline-flex items-center px-3 py-1 text-xs font-medium bg-deep-sea-blue/10 text-deep-sea-blue rounded-full">
Status: {statusValue.charAt(0).toUpperCase() + statusValue.slice(1)}
<button
type="button"
onClick={() => onStatusChange('')}
className="ml-2 hover:text-deep-sea-blue/70"
>
<X className="w-3 h-3" />
</button>
</span>
)}
{(dateFromValue || dateToValue) && (
<span className="inline-flex items-center px-3 py-1 text-xs font-medium bg-deep-sea-blue/10 text-deep-sea-blue rounded-full">
Date: {dateFromValue || '...'} to {dateToValue || '...'}
<button
type="button"
onClick={() => onDateRangeChange('', '')}
className="ml-2 hover:text-deep-sea-blue/70"
>
<X className="w-3 h-3" />
</button>
</span>
)}
</div>
)}
</div>
);
}