'use client' import React, { useEffect, useState } from 'react' import Select from 'react-select' import { SelectOption } from '@/app/types' import axios from 'axios' interface LocationOption extends SelectOption { value: string // добавляем поле value к базовому интерфейсу SelectOption } interface LocationSelectProps { name: string value: string handleChange: (e: { target: { id: string; value: string; selectedOption?: LocationOption } }) => void label: string placeholder: string countryId?: string isCity?: boolean } const LocationSelect: React.FC = ({ name, value, handleChange, label, placeholder, countryId, isCity = false, }) => { const [options, setOptions] = useState([]) const [isLoading, setIsLoading] = useState(false) const [search, setSearch] = useState('') const API_URL = process.env.NEXT_PUBLIC_API_URL useEffect(() => { const fetchOptions = async () => { setIsLoading(true) try { const url = isCity ? `${API_URL}/cities/?${countryId ? `country_id=${countryId}&` : ''}search=${search}` : `${API_URL}/countries/?search=${search}` const response = await axios.get(url) setOptions(response.data) } catch (error) { console.error('Error fetching options:', error) } finally { setIsLoading(false) } } // Debounce search const timeoutId = setTimeout(() => { fetchOptions() }, 300) return () => clearTimeout(timeoutId) }, [search, countryId, isCity, API_URL]) return (
inputId={name} name={name} options={options} value={options.find(opt => opt.value === value)} onChange={selectedOption => { handleChange({ target: { id: name, value: selectedOption?.value || '', selectedOption: selectedOption || undefined, }, }) }} isLoading={isLoading} onInputChange={newValue => setSearch(newValue)} isSearchable isClearable placeholder={placeholder} noOptionsMessage={() => (isLoading ? 'Загрузка...' : 'Нет доступных вариантов')} classNamePrefix="select" className="rounded-lg" styles={{ control: base => ({ ...base, borderRadius: '0.75rem', backgroundColor: '#F3F4F6', border: '1px solid #E5E7EB', padding: '2px', '&:hover': { borderColor: '#E5E7EB', }, '&:focus-within': { backgroundColor: '#FFFFFF', borderColor: '#E5E7EB', boxShadow: '0 0 0 2px rgba(59, 130, 246, 0.5)', }, }), menu: base => ({ ...base, position: 'absolute', width: '100%', zIndex: 9999, marginTop: '4px', borderRadius: '0.75rem', overflow: 'hidden', }), option: (base, state) => ({ ...base, fontSize: '0.875rem', padding: '8px 12px', backgroundColor: state.isSelected ? '#EFF6FF' : state.isFocused ? '#F3F4F6' : 'white', color: state.isSelected ? '#2563EB' : '#1F2937', cursor: 'pointer', '&:active': { backgroundColor: '#DBEAFE', }, '&:hover': { backgroundColor: state.isSelected ? '#EFF6FF' : '#F3F4F6', }, }), }} />
) } export default LocationSelect