/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable react/no-unescaped-entities */ /* eslint-disable @typescript-eslint/no-unused-vars */ import React, { useState, useEffect } from "react"; import { Field, ErrorMessage, FieldProps } from "formik"; import ThreeDotsLoader from "../Loader/ThreeDotsLoader"; // Define the types for the options interface SelectOption { id: string | number; name: string; } interface CustomSelectProps { name: string; options: SelectOption[]; label: string; icon: string; page?: string; isLoading?: boolean; allowNewOption?: boolean; isCreatable?: boolean; className?: string; width?: string; defaultValue?: string; onChange?: (value: any) => void; disabled?: boolean; } const CustomSelect: React.FC = ({ name, options, label, icon, page = "", isLoading = false, allowNewOption = false, isCreatable = false, className = "", width = "", defaultValue = "", onChange, disabled = false, }) => { const [showDropdown, setShowDropdown] = useState(false); const [inputValue, setInputValue] = useState(""); const [isInitialMount, setIsInitialMount] = useState(true); // Add useEffect to set initial value only on mount useEffect(() => { if (isInitialMount && defaultValue && options.length > 0) { const option = options.find((opt) => opt.id == defaultValue); if (option) { setInputValue(option.name); } setIsInitialMount(false); } }, [defaultValue, options, isInitialMount]); // Add effect to clear input value when field becomes disabled useEffect(() => { if (disabled) { setInputValue(""); } }, [disabled]); const filteredOptions = options?.length > 0 ? options.filter((opt: SelectOption) => { try { const searchValue = inputValue.toLowerCase(); const optionName = opt.name.toLowerCase(); return optionName.includes(searchValue); } catch { return false; } }) : []; const handleOptionSelect = (option: SelectOption, form: any) => { setInputValue(option.name); form.setFieldValue(name, option.id); if (onChange) { onChange({ value: option.id, label: option.name }); } setShowDropdown(false); }; const handleInputChange = ( e: React.ChangeEvent, form: any ) => { if (disabled) return; const newValue = e.target.value; setInputValue(newValue); // If input is cleared (backspace or delete), trigger onChange with null if (!newValue.trim()) { if (onChange) { onChange(null); } form.setFieldValue(name, ""); } else if (allowNewOption) { form.setFieldValue(name, newValue); } setShowDropdown(true); }; const handleAddNewOption = (form: any) => { if (disabled) return; if (inputValue.trim()) { const newOption: SelectOption = { id: inputValue.trim(), name: inputValue.trim(), }; setInputValue(newOption.name); form.setFieldValue(name, newOption.id); setShowDropdown(false); } }; const handleInputFocus = () => { if (disabled) return; setShowDropdown(true); }; const handleInputBlur = (form: any) => { setTimeout(() => { setShowDropdown(false); if (!inputValue.trim()) { form.setFieldValue(name, ""); if (onChange) { onChange(null); } } }, 200); }; return ( <> {page === "register" ? (
{/* */} {({ field, form }: FieldProps) => ( <> handleInputChange(e, form)} placeholder={label} style={{ minHeight: "28px", fontSize: "12px", padding: "0px 5px 0px 30px", }} onFocus={handleInputFocus} onBlur={() => handleInputBlur(form)} autoComplete="off" disabled={disabled} /> {isLoading && (
)} {showDropdown && (
{filteredOptions.length > 0 && ( <> {filteredOptions.map((option) => (
handleOptionSelect(option, form) } onMouseEnter={(e) => { e.currentTarget.style.backgroundColor = "#f5f5f5"; }} onMouseLeave={(e) => { e.currentTarget.style.backgroundColor = "#fff"; }} > {option.name}
))} )} {isCreatable && (
handleAddNewOption(form)} onMouseEnter={(e) => { e.currentTarget.style.backgroundColor = "#e9ecef"; }} onMouseLeave={(e) => { e.currentTarget.style.backgroundColor = "#f8f9fa"; }} > + Add "{inputValue}"
)} {!allowNewOption && filteredOptions.length === 0 && (
No options available
)}
)} )}
) : (
{/* */} {({ field, form }: FieldProps) => ( <> handleInputChange(e, form)} placeholder={label} style={{ minHeight: "28px", fontSize: "12px", padding: "0px 5px 0px 30px", }} onFocus={handleInputFocus} onBlur={() => handleInputBlur(form)} autoComplete="off" disabled={disabled} /> {isLoading && (
)} {showDropdown && (
{filteredOptions.length > 0 && ( <> {filteredOptions.map((option) => (
handleOptionSelect(option, form)} onMouseEnter={(e) => { e.currentTarget.style.backgroundColor = "#f5f5f5"; }} onMouseLeave={(e) => { e.currentTarget.style.backgroundColor = "#fff"; }} > {option.name}
))} )} {isCreatable && (
handleAddNewOption(form)} onMouseEnter={(e) => { e.currentTarget.style.backgroundColor = "#e9ecef"; }} onMouseLeave={(e) => { e.currentTarget.style.backgroundColor = "#f8f9fa"; }} > + Add "{inputValue}"
)} {!allowNewOption && filteredOptions.length === 0 && (
No options available
)}
)} )}
)} ); }; export default CustomSelect;