'use client'; import { useEffect, useMemo, useState } from 'react'; import { Bot, Loader2 } from 'lucide-react'; import { AvatarWithPresence } from '@/components/family/avatar-with-presence'; import { useAuth } from '@/components/id/auth-provider'; import { useToast } from '@/components/id/toast-provider'; import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'; import { Input } from '@/components/ui/input'; import { FamilyGroup, FamilyInviteCandidate, ManagedBot, fetchMyBots, getApiErrorMessage, searchFamilyInviteUsers, sendFamilyInvite } from '@/lib/api'; export function FamilyInviteDialog({ groupId, group, open, onOpenChange, onInvited }: { groupId: string; group?: FamilyGroup | null; open: boolean; onOpenChange: (open: boolean) => void; onInvited?: () => void; }) { const { token } = useAuth(); const { showToast } = useToast(); const [inviteQuery, setInviteQuery] = useState(''); const [inviteResults, setInviteResults] = useState([]); const [inviteSearching, setInviteSearching] = useState(false); const [selectedInviteUser, setSelectedInviteUser] = useState(null); const [submitting, setSubmitting] = useState(false); const [myBots, setMyBots] = useState([]); const [myBotsLoading, setMyBotsLoading] = useState(false); const familyBotUsernames = useMemo( () => new Set((group?.members ?? []).map((member) => member.botUsername).filter(Boolean) as string[]), [group?.members] ); const availableMyBots = useMemo( () => myBots.filter((bot) => !familyBotUsernames.has(bot.username)), [familyBotUsernames, myBots] ); useEffect(() => { if (!open) { setInviteQuery(''); setInviteResults([]); setSelectedInviteUser(null); setMyBots([]); return; } if (!token) return; setMyBotsLoading(true); fetchMyBots(token) .then((response) => setMyBots(response.bots ?? [])) .catch(() => setMyBots([])) .finally(() => setMyBotsLoading(false)); }, [open, token]); useEffect(() => { if (!open) return; if (!token || inviteQuery.trim().length < 2) { setInviteResults([]); return; } const timer = window.setTimeout(() => { setInviteSearching(true); searchFamilyInviteUsers(groupId, inviteQuery.trim(), token) .then((response) => setInviteResults(response.users ?? [])) .catch(() => setInviteResults([])) .finally(() => setInviteSearching(false)); }, 300); return () => window.clearTimeout(timer); }, [groupId, inviteQuery, open, token]); async function submitInvite() { if (!token || !selectedInviteUser) return; setSubmitting(true); try { await sendFamilyInvite(groupId, { inviteeUserId: selectedInviteUser.id }, token); if (selectedInviteUser.isBot) { showToast(`${selectedInviteUser.displayName} добавлен в семью`); } else { showToast('Приглашение отправлено'); } onOpenChange(false); onInvited?.(); } catch (error) { showToast( getApiErrorMessage( error, selectedInviteUser.isBot ? 'Не удалось добавить бота' : 'Не удалось отправить приглашение' ) ?? 'Ошибка' ); } finally { setSubmitting(false); } } function botCandidateLabel(candidate: FamilyInviteCandidate) { if (!candidate.isBot) { return candidate.email ?? candidate.phone ?? candidate.username ?? 'Без контактов'; } const handle = `@${candidate.botUsername ?? 'bot'}`; if (candidate.ownerDisplayName) { return `${handle} · владелец: ${candidate.ownerDisplayName}`; } if (candidate.botUsername === 'BotFather_bot') { return `${handle} — создавайте ботов через чат`; } if (candidate.botUsername === 'GetMyIdBot_bot') { return `${handle} — получите user_id и chat_id`; } return handle; } function submitButtonLabel() { if (!selectedInviteUser?.isBot) return 'Отправить приглашение'; return 'Пригласить бота'; } return ( Пригласить в семью {selectedInviteUser ? (

{selectedInviteUser.displayName} {selectedInviteUser.isBot ? ' 🤖' : ''}

{botCandidateLabel(selectedInviteUser)}

) : ( <> setInviteQuery(event.target.value)} /> {inviteQuery.trim().length < 2 ? (

Мои боты

{myBotsLoading ? (
Загрузка ботов...
) : availableMyBots.length ? ( availableMyBots.map((bot) => ( )) ) : (

{myBots.length ? 'Все ваши боты уже в семье' : 'У вас пока нет ботов. Создайте через BotFather.'}

)}

Выберите своего бота, затем подтвердите приглашение в результатах поиска

) : null}
{inviteSearching ? (
Ищем...
) : inviteQuery.trim().length < 2 ? (

Введите минимум 2 символа для поиска пользователей и ботов

) : inviteResults.length ? ( inviteResults.map((candidate) => ( )) ) : (

Ничего не найдено

)}
)}
); }