diff --git a/frontend/src/app/employees/page.tsx b/frontend/src/app/employees/page.tsx index 8f840fbc..25e580cc 100644 --- a/frontend/src/app/employees/page.tsx +++ b/frontend/src/app/employees/page.tsx @@ -4,20 +4,25 @@ import { AppShell } from "../../components/AppShell"; import { apiClient } from "@/lib/api"; import { useEffect, useRef, useState } from "react"; import Link from "next/link"; +import { useRouter } from "next/navigation"; +import { MessageCircle } from "lucide-react"; +import { useUser } from "@/contexts/UserContext"; import type { User } from "@/types/api"; export default function EmployeesPage() { + const router = useRouter(); + const { user: currentUser } = useUser(); const [employees, setEmployees] = useState([]); const [loading, setLoading] = useState(true); const [loadingMore, setLoadingMore] = useState(false); const [error, setError] = useState(null); const [page, setPage] = useState(1); const [hasMore, setHasMore] = useState(true); - const [showOnlyActive, setShowOnlyActive] = useState(false); + const [creatingChatFor, setCreatingChatFor] = useState(null); const loaderRef = useRef(null); const isFetchingRef = useRef(false); - const loadEmployees = async (pageToLoad: number, append: boolean, activeOnly: boolean) => { + const loadEmployees = async (pageToLoad: number, append: boolean) => { if (isFetchingRef.current) return; try { @@ -32,7 +37,7 @@ export default function EmployeesPage() { const response = await apiClient.getEmployees({ page: pageToLoad, limit: 20, - ...(activeOnly && { is_active: true }) + is_active: true }); const nextChunk = response.results || []; @@ -50,8 +55,49 @@ export default function EmployeesPage() { }; useEffect(() => { - loadEmployees(1, false, showOnlyActive); - }, [showOnlyActive]); + loadEmployees(1, false); + }, []); + + // Создание чата с сотрудником + const handleStartChat = async (employee: User, e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + + if (!currentUser || creatingChatFor === employee.id) return; + if (currentUser.id === employee.id) return; // Не создаем чат с собой + + setCreatingChatFor(employee.id); + try { + // Ищем существующий приватный чат с этим пользователем + const chatsResponse = await apiClient.getChats(); + const allChats = chatsResponse.results || chatsResponse; + + const existingChat = allChats.find((chat: any) => { + if (chat.type !== 'private') return false; + + const memberIds: number[] = chat.member_ids || []; + return memberIds.length === 2 && + memberIds.includes(currentUser.id) && + memberIds.includes(employee.id); + }); + + if (existingChat) { + router.push(`/messages/${existingChat.id}`); + } else { + const chat = await apiClient.createChat({ + type: 'private', + name: 'Диалог', + participants: [employee.id] + }); + router.push(`/messages/${chat.id}`); + } + } catch (err: any) { + console.error("Ошибка создания чата:", err); + alert("Не удалось открыть чат"); + } finally { + setCreatingChatFor(null); + } + }; useEffect(() => { if (!hasMore || loading) return; @@ -64,7 +110,7 @@ export default function EmployeesPage() { const first = entries[0]; if (!first?.isIntersecting) return; if (isFetchingRef.current || loadingMore || !hasMore) return; - loadEmployees(page + 1, true, showOnlyActive); + loadEmployees(page + 1, true); }, { root: null, @@ -111,52 +157,46 @@ export default function EmployeesPage() { return ( -
- - -
-
{sortedEmployees.map((employee) => { const fullName = `${employee.last_name} ${employee.first_name} ${employee.patronymic || ''}`.trim(); const initials = `${employee.last_name?.[0] || ''}${employee.first_name?.[0] || ''}`; const position = employee.position?.name || 'Сотрудник'; + const isCurrentUser = currentUser?.id === employee.id; return ( - -
- {employee.avatar ? ( - {fullName} - ) : ( - initials - )} -
-
-

{fullName}

-

{position}

- {employee.email && ( -

{employee.email}

- )} -
- +
+ +
+ {employee.avatar ? ( + {fullName} + ) : ( + initials + )} +
+
+

{fullName}

+

{position}

+ {employee.email && ( +

{employee.email}

+ )} +
+ + {!isCurrentUser && ( + + )} +
); })}