import React, { useState, useRef, useEffect } from "react"; interface Stock { store: string; storeName: string; quantity: number; work: boolean; blocked: string; breakdown: number; transfer: number; allowDelivery: number; } interface FilialSelectorProps { stocks: Stock[]; value?: string; onValueChange?: (value: string) => void; placeholder?: string; label?: string; className?: string; } const FilialSelector: React.FC = ({ stocks, value, onValueChange, placeholder = "Selecione a filial retira", label = "Filial Retira", className, }) => { const [isOpen, setIsOpen] = useState(false); const [searchTerm, setSearchTerm] = useState(""); const [selectedStore, setSelectedStore] = useState(value || ""); const [displayValue, setDisplayValue] = useState(""); const containerRef = useRef(null); const inputRef = useRef(null); const tableRef = useRef(null); // Atualizar selectedStore e displayValue quando value mudar externamente useEffect(() => { if (value !== undefined) { setSelectedStore(value); const selected = stocks.find((s) => s.store === value); if (selected) { setDisplayValue(selected.storeName); setSearchTerm(selected.storeName); } else { setDisplayValue(""); setSearchTerm(""); } } }, [value, stocks]); // Fechar dropdown ao clicar fora useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if ( containerRef.current && !containerRef.current.contains(event.target as Node) ) { setIsOpen(false); // Restaurar displayValue quando fechar sem selecionar if (selectedStore) { const selected = stocks.find((s) => s.store === selectedStore); if (selected) { setSearchTerm(selected.storeName); setDisplayValue(selected.storeName); } } else { setSearchTerm(""); setDisplayValue(""); } } }; if (isOpen) { document.addEventListener("mousedown", handleClickOutside); return () => { document.removeEventListener("mousedown", handleClickOutside); }; } }, [isOpen, selectedStore, stocks]); // Filtrar estoques baseado no termo de busca (busca em store e storeName) const filteredStocks = stocks.filter((stock) => { if (!searchTerm) return true; const search = searchTerm.toLowerCase(); return ( stock.store.toLowerCase().includes(search) || stock.storeName.toLowerCase().includes(search) ); }); const handleSelect = (store: string) => { setSelectedStore(store); const stock = stocks.find((s) => s.store === store); if (stock) { setDisplayValue(stock.storeName); setSearchTerm(stock.storeName); } onValueChange?.(store); setIsOpen(false); }; const handleClear = () => { setSearchTerm(""); setDisplayValue(""); setSelectedStore(""); onValueChange?.(""); if (inputRef.current) { inputRef.current.focus(); } setIsOpen(true); }; const handleInputChange = (e: React.ChangeEvent) => { const newValue = e.target.value; setSearchTerm(newValue); setDisplayValue(newValue); setIsOpen(true); // Se limpar o input, limpar também a seleção if (!newValue) { setSelectedStore(""); onValueChange?.(""); } }; const handleInputFocus = () => { setIsOpen(true); // Quando focar, mostrar o termo de busca atual if (selectedStore) { const selected = stocks.find((s) => s.store === selectedStore); if (selected) { setSearchTerm(selected.storeName); } } }; const handleToggleDropdown = () => { setIsOpen(!isOpen); if (!isOpen && inputRef.current) { inputRef.current.focus(); } }; const formatNumber = (num: number): string => { return num.toLocaleString("pt-BR", { minimumFractionDigits: 3, maximumFractionDigits: 3, }); }; return (
{label && ( )}
{/* Input */}
{/* Botões de ação */}
{(searchTerm || displayValue) && ( )}
{/* Dropdown com Tabela */} {isOpen && (
{/* Tabela */}
{filteredStocks.length === 0 ? ( ) : ( filteredStocks.map((stock) => { const isSelected = stock.store === selectedStore; return ( handleSelect(stock.store)} className={`cursor-pointer transition-colors ${ isSelected ? "bg-blue-50 hover:bg-blue-100" : "hover:bg-slate-50" }`} > ); }) )}
Loja Nome da Loja Entrega Estoque Pertence Bloq Transf
Nenhuma filial encontrada
{stock.store} {stock.storeName} {formatNumber(stock.quantity)} {stock.blocked || "0"} {stock.transfer || 0}
)}
); }; export default FilialSelector;