diff options
Diffstat (limited to 'makima/frontend/src/components/history')
| -rw-r--r-- | makima/frontend/src/components/history/HistoryFilters.tsx | 81 |
1 files changed, 69 insertions, 12 deletions
diff --git a/makima/frontend/src/components/history/HistoryFilters.tsx b/makima/frontend/src/components/history/HistoryFilters.tsx index a1a4945..3be50ad 100644 --- a/makima/frontend/src/components/history/HistoryFilters.tsx +++ b/makima/frontend/src/components/history/HistoryFilters.tsx @@ -1,3 +1,4 @@ +import { useState, useRef, useEffect } from "react"; import type { ContractSummary } from "../../lib/api"; interface HistoryFiltersProps { @@ -21,23 +22,79 @@ export function HistoryFilters({ onDateToChange, totalCount, }: HistoryFiltersProps) { + const [isDropdownOpen, setIsDropdownOpen] = useState(false); + const dropdownRef = useRef<HTMLDivElement>(null); + + // Get the selected contract name for display + const selectedContract = contracts.find((c) => c.id === selectedContractId); + const displayText = selectedContract ? selectedContract.name : "All Contracts"; + + // Close dropdown when clicking outside + useEffect(() => { + function handleClickOutside(event: MouseEvent) { + if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) { + setIsDropdownOpen(false); + } + } + + if (isDropdownOpen) { + document.addEventListener("mousedown", handleClickOutside); + return () => document.removeEventListener("mousedown", handleClickOutside); + } + }, [isDropdownOpen]); + + const handleSelect = (contractId: string | null) => { + onContractChange(contractId); + setIsDropdownOpen(false); + }; + return ( <div className="shrink-0 flex items-center gap-4 p-3 border border-[rgba(117,170,252,0.15)] bg-[rgba(0,0,0,0.2)]"> {/* Contract filter */} <div className="flex items-center gap-2"> <label className="font-mono text-[10px] text-[#7788aa] uppercase">Contract</label> - <select - value={selectedContractId || ""} - onChange={(e) => onContractChange(e.target.value || null)} - className="font-mono text-xs text-[#9bc3ff] bg-[#0a1525] border border-[rgba(117,170,252,0.25)] px-2 py-1 focus:border-[#3f6fb3] focus:outline-none min-w-[150px]" - > - <option value="">All Contracts</option> - {contracts.map((contract) => ( - <option key={contract.id} value={contract.id}> - {contract.name} - </option> - ))} - </select> + <div className="relative" ref={dropdownRef}> + <button + type="button" + onClick={() => setIsDropdownOpen(!isDropdownOpen)} + className="font-mono text-xs text-[#9bc3ff] bg-[#0a1525] border border-[rgba(117,170,252,0.25)] px-2 py-1 focus:border-[#3f6fb3] focus:outline-none min-w-[150px] text-left flex items-center justify-between gap-2" + > + <span className="truncate">{displayText}</span> + <svg + className={`w-3 h-3 transition-transform ${isDropdownOpen ? "rotate-180" : ""}`} + fill="none" + stroke="currentColor" + viewBox="0 0 24 24" + > + <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" /> + </svg> + </button> + {isDropdownOpen && ( + <div className="absolute top-full left-0 mt-1 min-w-[200px] max-h-[300px] overflow-y-auto bg-[#0a1525] border border-[rgba(117,170,252,0.25)] z-50 shadow-lg"> + <button + type="button" + onClick={() => handleSelect(null)} + className={`w-full text-left font-mono text-xs px-2 py-1.5 hover:bg-[rgba(117,170,252,0.1)] transition-colors ${ + selectedContractId === null ? "text-[#75aafc] bg-[rgba(117,170,252,0.05)]" : "text-[#9bc3ff]" + }`} + > + All Contracts + </button> + {contracts.map((contract) => ( + <button + type="button" + key={contract.id} + onClick={() => handleSelect(contract.id)} + className={`w-full text-left font-mono text-xs px-2 py-1.5 hover:bg-[rgba(117,170,252,0.1)] transition-colors ${ + selectedContractId === contract.id ? "text-[#75aafc] bg-[rgba(117,170,252,0.05)]" : "text-[#9bc3ff]" + }`} + > + {contract.name} + </button> + ))} + </div> + )} + </div> </div> {/* Date range */} |
