diff --git a/package.json b/package.json index a8c8333..68fb8b2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "vite-react-typescript-starter", "private": true, - "version": "1.2.6", + "version": "1.2.7", "type": "module", "scripts": { "dev": "vite", diff --git a/src/components/AuthorSelectionModal.tsx b/src/components/AuthorSelectionModal.tsx index e0f16ec..56ea906 100644 --- a/src/components/AuthorSelectionModal.tsx +++ b/src/components/AuthorSelectionModal.tsx @@ -1,6 +1,6 @@ -import React, { useState, useMemo } from 'react'; +import React, { useState, useMemo, useEffect } from 'react'; import { Author, AuthorRole } from '../types'; -import { X, ChevronLeft, ChevronRight } from 'lucide-react'; +import { X, ChevronLeft, ChevronRight, Search } from 'lucide-react'; import { CSSTransition, TransitionGroup } from 'react-transition-group'; interface AuthorSelectionModalProps { @@ -28,6 +28,7 @@ const AuthorSelectionModal: React.FC = ({ const [activeTab, setActiveTab] = useState(AuthorRole.WRITER); const [selectedAuthorId, setSelectedAuthorId] = useState(null); const [currentPage, setCurrentPage] = useState(1); + const [searchTerm, setSearchTerm] = useState(''); const itemsPerPage = 10; // Используем useMemo для оптимальной фильтрации и сортировки авторов @@ -50,31 +51,48 @@ const AuthorSelectionModal: React.FC = ({ return { popularAuthors, otherAuthors }; }, [authors, existingAuthors, activeTab]); - // Вычисляем данные для пагинации только для остальных авторов - const paginationData = useMemo(() => { - const showPagination = otherAuthors.length > itemsPerPage; + // Фильтруем остальных авторов по поисковому запросу + const filteredOtherAuthors = useMemo(() => { + if (!searchTerm.trim()) { + return otherAuthors; + } - // Если пагинация не нужна, показываем всех остальных авторов + const searchLower = searchTerm.toLowerCase().trim(); + return otherAuthors.filter(author => + author.displayName.toLowerCase().startsWith(searchLower) + ); + }, [otherAuthors, searchTerm]); + + // Вычисляем данные для пагинации только для отфильтрованных остальных авторов + const paginationData = useMemo(() => { + const showPagination = filteredOtherAuthors.length > itemsPerPage; + + // Если пагинация не нужна, показываем всех отфильтрованных остальных авторов if (!showPagination) { return { showPagination: false, - displayedOtherAuthors: otherAuthors, + displayedOtherAuthors: filteredOtherAuthors, totalPages: 1 }; } // Если пагинация нужна - const totalPages = Math.ceil(otherAuthors.length / itemsPerPage); + const totalPages = Math.ceil(filteredOtherAuthors.length / itemsPerPage); const startIndex = (currentPage - 1) * itemsPerPage; const endIndex = startIndex + itemsPerPage; - const displayedOtherAuthors = otherAuthors.slice(startIndex, endIndex); + const displayedOtherAuthors = filteredOtherAuthors.slice(startIndex, endIndex); return { showPagination: true, displayedOtherAuthors, totalPages }; - }, [otherAuthors, currentPage, itemsPerPage]); + }, [filteredOtherAuthors, currentPage, itemsPerPage]); + + // Сбрасываем страницу при изменении поискового запроса + useEffect(() => { + setCurrentPage(1); + }, [searchTerm]); const handleAddAuthor = () => { if (selectedAuthorId) { @@ -87,6 +105,7 @@ const AuthorSelectionModal: React.FC = ({ const handleTabChange = (role: AuthorRole) => { setActiveTab(role); setCurrentPage(1); + setSearchTerm(''); setSelectedAuthorId(null); }; @@ -96,6 +115,14 @@ const AuthorSelectionModal: React.FC = ({ document.getElementById('other-authors-section')?.scrollIntoView({ behavior: 'smooth' }); }; + const handleSearchChange = (e: React.ChangeEvent) => { + setSearchTerm(e.target.value); + }; + + const clearSearch = () => { + setSearchTerm(''); + }; + if (!isOpen) return null; const { showPagination, displayedOtherAuthors, totalPages } = paginationData; @@ -174,7 +201,7 @@ const AuthorSelectionModal: React.FC = ({ )} - {/* Все остальные авторы с пагинацией */} + {/* Все остальные авторы с поиском и пагинацией */}

@@ -187,6 +214,35 @@ const AuthorSelectionModal: React.FC = ({ )}

+ {/* Поле поиска */} +
+
+
+ +
+ + {searchTerm && ( + + )} +
+ {searchTerm && ( +

+ Найдено: {filteredOtherAuthors.length} {filteredOtherAuthors.length === 1 ? 'автор' : 'авторов'} +

+ )} +
+ {displayedOtherAuthors.length > 0 ? ( <>
@@ -248,7 +304,10 @@ const AuthorSelectionModal: React.FC = ({ ) : (

- Нет доступных + {searchTerm + ? `Нет авторов, начинающихся с "${searchTerm}"` + : `Нет доступных ${roleLabels[activeTab].toLowerCase()}` + }

)}