diff --git a/frontend/src/app/employees/page.tsx b/frontend/src/app/employees/page.tsx index 425fb339..1a8945b5 100644 --- a/frontend/src/app/employees/page.tsx +++ b/frontend/src/app/employees/page.tsx @@ -3,8 +3,8 @@ import Image from "next/image"; import Link from "next/link"; import { useRouter } from "next/navigation"; -import { useEffect, useRef, useState, type MouseEvent } from "react"; -import { MessageCircle } from "lucide-react"; +import { useEffect, useMemo, useRef, useState, type MouseEvent } from "react"; +import { MessageCircle, Search } from "lucide-react"; import { AppShell } from "../../components/AppShell"; import { useUser } from "@/contexts/UserContext"; @@ -28,6 +28,7 @@ export default function EmployeesPage() { const [loading, setLoading] = useState(true); const [loadingMore, setLoadingMore] = useState(false); const [error, setError] = useState(null); + const [search, setSearch] = useState(""); const [page, setPage] = useState(1); const [hasMore, setHasMore] = useState(true); const [creatingChatFor, setCreatingChatFor] = useState(null); @@ -141,6 +142,25 @@ export default function EmployeesPage() { }; }, [hasMore, loading, loadingMore, page]); + const filteredEmployees = useMemo(() => { + const sorted = [...employees].sort((left, right) => { + const leftName = `${left.last_name || ""} ${left.first_name || ""}`.trim(); + const rightName = `${right.last_name || ""} ${right.first_name || ""}`.trim(); + return leftName.localeCompare(rightName, "ru"); + }); + + const query = search.trim().toLowerCase(); + if (!query) return sorted; + + return sorted.filter((employee) => { + const fullName = + `${employee.last_name || ""} ${employee.first_name || ""} ${employee.patronymic || ""}`.trim().toLowerCase(); + const position = (employee.position?.name || "").toLowerCase(); + const email = (employee.email || "").toLowerCase(); + return fullName.includes(query) || position.includes(query) || email.includes(query); + }); + }, [employees, search]); + if (loading) { return ( @@ -162,17 +182,21 @@ export default function EmployeesPage() { ); } - const sortedEmployees = [...employees].sort((left, right) => { - const leftName = `${left.last_name || ""} ${left.first_name || ""}`.trim(); - const rightName = `${right.last_name || ""} ${right.first_name || ""}`.trim(); - return leftName.localeCompare(rightName, "ru"); - }); - return (
+
+ + setSearch(event.target.value)} + placeholder="Поиск по сотрудникам" + className="app-input w-full rounded-lg py-2.5 pl-9 pr-3 text-sm" + /> +
+
- {sortedEmployees.map((employee) => { + {filteredEmployees.map((employee) => { const fullName = `${employee.last_name || ""} ${employee.first_name || ""} ${employee.patronymic || ""}`.trim(); const initials = getInitials(employee); @@ -236,6 +260,12 @@ export default function EmployeesPage() { ); })} + {filteredEmployees.length === 0 ? ( +
+

Сотрудники не найдены

+
+ ) : null} +
{loadingMore ? (