/** * Кастомный селектор предметов с поиском */ 'use client'; import React, { useState, useRef, useEffect } from 'react'; import { Subject, MentorSubject } from '@/api/subjects'; interface SubjectSelectProps { subjects: Subject[]; mentorSubjects: MentorSubject[]; value: number | null; onChange: (value: number | null) => void; disabled?: boolean; required?: boolean; } export const SubjectSelect: React.FC = ({ subjects, mentorSubjects, value, onChange, disabled = false, required = false, }) => { const [isOpen, setIsOpen] = useState(false); const [searchQuery, setSearchQuery] = useState(''); const containerRef = useRef(null); const searchInputRef = useRef(null); // Объединяем все предметы const allSubjects = [ ...subjects.map(s => ({ ...s, type: 'standard' as const })), ...mentorSubjects.map(s => ({ ...s, type: 'mentor' as const })), ]; // Получаем выбранный предмет const selectedSubject = allSubjects.find(s => s.id === value); // Фильтруем предметы по поисковому запросу const filteredSubjects = allSubjects.filter(subject => { const name = subject.name.toLowerCase(); const query = searchQuery.toLowerCase(); return name.includes(query); }); // Группируем предметы по типу const standardSubjects = filteredSubjects.filter(s => s.type === 'standard'); const mentorSubjectsFiltered = filteredSubjects.filter(s => s.type === 'mentor'); // Закрываем dropdown при клике вне компонента useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (containerRef.current && !containerRef.current.contains(event.target as Node)) { setIsOpen(false); setSearchQuery(''); } }; if (isOpen) { document.addEventListener('mousedown', handleClickOutside); // Фокусируем поле поиска при открытии setTimeout(() => searchInputRef.current?.focus(), 0); } return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, [isOpen]); const handleSelect = (subjectId: number) => { onChange(subjectId); setIsOpen(false); setSearchQuery(''); }; return (
{/* Основная кнопка выбора */} {/* Dropdown меню */} {isOpen && (
{/* Поле поиска */}
setSearchQuery(e.target.value)} placeholder="Поиск предмета..." style={{ width: '100%', padding: '8px 12px 8px 40px', fontSize: '14px', color: 'var(--md-sys-color-on-surface)', background: 'var(--md-sys-color-surface-variant)', border: 'none', borderRadius: '8px', fontFamily: 'inherit', outline: 'none', }} /> {searchQuery && ( )}
{/* Список предметов */}
{filteredSubjects.length === 0 ? (
{searchQuery ? 'Предметы не найдены' : 'Нет доступных предметов'}
) : ( <> {/* Стандартные предметы */} {standardSubjects.length > 0 && ( <> {!searchQuery && (
Стандартные предметы
)} {standardSubjects.map((subject) => ( ))} )} {/* Предметы ментора */} {mentorSubjectsFiltered.length > 0 && ( <> {!searchQuery && standardSubjects.length > 0 && (
Мои предметы
)} {mentorSubjectsFiltered.map((subject) => ( ))} )} )}
)}
); };