'use client'; import { useState, useEffect, useCallback } from 'react'; import { useAuth } from '@/contexts/AuthContext'; import { useRouter } from 'next/navigation'; import { sendMentorshipRequest, getMyMentorshipRequests, getMyMentors, getMyInvitations, confirmInvitationAsStudent, rejectInvitationAsStudent, type MentorInvitation } from '@/api/students'; import { format } from 'date-fns'; import { ru } from 'date-fns/locale'; import { loadComponent } from '@/lib/material-components'; export default function RequestMentorPage() { const { user, loading: authLoading } = useAuth(); const router = useRouter(); const [componentsLoaded, setComponentsLoaded] = useState(false); const [mentorCode, setMentorCode] = useState(''); const [submitting, setSubmitting] = useState(false); const [success, setSuccess] = useState(false); const [addError, setAddError] = useState(''); const [showAddPanel, setShowAddPanel] = useState(false); const [activeTab, setActiveTab] = useState<'connect' | 'awaiting' | 'invitations'>('connect'); const [myRequests, setMyRequests] = useState>([]); const [loadingRequests, setLoadingRequests] = useState(false); const [myMentors, setMyMentors] = useState>([]); const [myInvitations, setMyInvitations] = useState([]); const [loadingInvitations, setLoadingInvitations] = useState(false); const [confirmingId, setConfirmingId] = useState(null); const [rejectingId, setRejectingId] = useState(null); const [invitationError, setInvitationError] = useState(null); const loadData = useCallback(() => { if (user?.role !== 'client') return; setLoadingRequests(true); setLoadingInvitations(true); Promise.all([ getMyMentorshipRequests(), getMyMentors(), getMyInvitations(), ]) .then(([requests, mentors, invitations]) => { setMyRequests(requests); setMyMentors(mentors); setMyInvitations(invitations); setInvitationError(null); }) .catch(() => {}) .finally(() => { setLoadingRequests(false); setLoadingInvitations(false); }); }, [user?.role]); useEffect(() => { loadComponent('elevated-card').then(() => setComponentsLoaded(true)).catch(() => setComponentsLoaded(true)); }, []); useEffect(() => { if (user?.role !== 'client') { router.replace('/dashboard'); return; } }, [user, router]); useEffect(() => { loadData(); }, [loadData]); const handleSubmit = async () => { setAddError(''); const code = mentorCode.trim().toUpperCase().replace(/[^A-Z0-9]/g, '').slice(0, 8); if (code.length !== 8) { setAddError('Введите 8-символьный код (цифры и латинские буквы)'); return; } setSubmitting(true); try { await sendMentorshipRequest(code); setSuccess(true); setMentorCode(''); setActiveTab('awaiting'); // Показать вкладку с отправленным запросом loadData(); } catch (err: any) { setAddError(err?.response?.data?.error || 'Не удалось отправить запрос'); } finally { setSubmitting(false); } }; if (authLoading || !user) { return (
Загрузка...
); } if (user?.role !== 'client') { return null; } if (!componentsLoaded) { return (
Загрузка...
); } const pendingRequests = myRequests.filter((r) => r.status === 'pending_mentor' || r.status === 'pending'); const pendingInvitationsFromMentors = myInvitations.filter((i) => ['pending_student', 'pending_parent', 'pending'].includes(i.status) ); const rejectedRequests = myRequests.filter((r) => r.status === 'rejected'); return (
{/* Табы всегда видны — Менторы | Ожидают ответа (ваши запросы) | Входящие приглашения (от менторов) */}
{loadingRequests || loadingInvitations ? (
Загрузка...
) : activeTab === 'invitations' ? ( pendingInvitationsFromMentors.length === 0 ? (

Нет входящих приглашений

) : (
{invitationError && (
{invitationError}
)}
{pendingInvitationsFromMentors.map((inv) => { const mentorName = [inv.mentor?.first_name, inv.mentor?.last_name].filter(Boolean).join(' ') || inv.mentor?.email || 'Ментор'; const initials = [inv.mentor?.first_name?.[0], inv.mentor?.last_name?.[0]].filter(Boolean).map((c) => c?.toUpperCase()).join('') || inv.mentor?.email?.[0]?.toUpperCase() || 'М'; return (
{initials}
{mentorName}
{inv.mentor?.email}
{inv.created_at && (
{format(new Date(inv.created_at), 'd MMM yyyy, HH:mm', { locale: ru })}
)} {inv.status === 'pending_parent' ? ( Ожидаем подтверждения родителя ) : (
)}
); })}
) ) : activeTab === 'awaiting' ? ( pendingRequests.length === 0 ? (

Нет запросов, ожидающих ответа

) : (
{pendingRequests.map((r) => { const mentorName = [r.mentor?.first_name, r.mentor?.last_name].filter(Boolean).join(' ') || r.mentor?.email || 'Ментор'; const initials = [r.mentor?.first_name?.[0], r.mentor?.last_name?.[0]].filter(Boolean).map((c) => c?.toUpperCase()).join('') || r.mentor?.email?.[0]?.toUpperCase() || 'М'; return (
{initials}
{mentorName}
{r.mentor?.email || '—'}
{r.created_at && (
{format(new Date(r.created_at), 'd MMM yyyy, HH:mm', { locale: ru })}
)} Ожидает
); })}
) ) : (
{/* Карточки подключённых менторов (из client.mentors — включая принятые приглашения) */} {myMentors.map((m) => { const mentorName = [m.first_name, m.last_name].filter(Boolean).join(' ') || m.email || 'Ментор'; const initials = [m.first_name?.[0], m.last_name?.[0]].filter(Boolean).map((c) => c?.toUpperCase()).join('') || m.email?.[0]?.toUpperCase() || 'М'; const avatarUrl = m.avatar_url || null; const req = myRequests.find((r) => r.mentor?.id === m.id); const statusLabel = 'Принято'; const statusBg = 'var(--md-sys-color-primary-container)'; const statusColor = 'var(--md-sys-color-on-primary-container)'; return (
{avatarUrl ? ( // eslint-disable-next-line @next/next/no-img-element {mentorName} ) : (
{initials}
)}
{mentorName}
{m.email || '—'}
{req?.created_at && (
{format(new Date(req.created_at), 'd MMM yyyy, HH:mm', { locale: ru })}
)} {statusLabel}
); })} {/* Карточки отклонённых запросов */} {rejectedRequests.map((r) => { const mentorName = [r.mentor?.first_name, r.mentor?.last_name].filter(Boolean).join(' ') || r.mentor?.email || 'Ментор'; const initials = [r.mentor?.first_name?.[0], r.mentor?.last_name?.[0]].filter(Boolean).map((c) => c?.toUpperCase()).join('') || r.mentor?.email?.[0]?.toUpperCase() || 'М'; return (
{initials}
{mentorName}
{r.mentor?.email || '—'}
{r.created_at && (
{format(new Date(r.created_at), 'd MMM yyyy, HH:mm', { locale: ru })}
)} Отклонено
); })} {/* Карточка «Подключиться к ментору» */} { setShowAddPanel(true); setAddError(''); setSuccess(false); setMentorCode(''); }} >
+
Подключиться к ментору
Введите код ментора
)} {/* Боковая панель с формой (как на странице студентов) */} {showAddPanel && (
Подключиться к ментору
Введите 8-символьный код ментора
{success ? (
Запрос отправлен. Ожидайте ответа ментора.
) : ( <> { const v = e.target.value.toUpperCase().replace(/[^A-Z0-9]/g, '').slice(0, 8); setMentorCode(v); setAddError(''); }} placeholder="A1B2C3D4" disabled={submitting} style={{ width: '100%', padding: '14px 16px', borderRadius: 12, border: `1px solid ${addError ? 'var(--md-sys-color-error)' : 'var(--md-sys-color-outline)'}`, background: 'var(--md-sys-color-surface-container-low)', color: 'var(--md-sys-color-on-surface)', fontSize: 18, letterSpacing: 4, boxSizing: 'border-box', }} /> {addError && (

{addError}

)}

Ментор получит уведомление и сможет принять или отклонить запрос.

)} {user?.universal_code && (
Ваш 8-символьный код
{(user.universal_code || '').split('').map((char, i) => ( {char} ))}
Поделитесь кодом с ментором — он сможет добавить вас по приглашению
)}
)}
); }