import { useEffect, useState, useRef } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { Card, CardContent, CardHeader, CardTitle } from '../ui/card'; import { Button } from '../ui/button'; import { Clock, ArrowLeft } from 'lucide-react'; import { useLanguage } from '../../lib/languageContext'; import { useAuth } from '../../lib/authContext'; import { getApiBaseUrl } from '../../lib/api/config'; const POLL_INTERVAL_MS = 5000; const translations = { ar: { title: 'في انتظار انتهاء الجلسة', subtitle: 'الجلسة لا تزال جارية', waitingMessage: 'الشيخ سيُنهي الجلسة عند الانتهاء من الدرس. ستُنقل تلقائيًا إلى تقرير الجلسة.', with: 'مع', scheduledAt: 'وقت الجلسة', backToSessions: 'العودة إلى الجلسات', sessionEnded: 'انتهت الجلسة، جارٍ التحويل...', sessionMissed: 'لم تُعقد الجلسة، جارٍ التحويل...', loading: 'جاري التحميل...', error: 'تعذّر تحميل بيانات الجلسة.', }, en: { title: 'Waiting for Session to End', subtitle: 'Session is still ongoing', waitingMessage: 'The sheikh will end the session when the lesson is complete. You will be redirected to the session report automatically.', with: 'with', scheduledAt: 'Scheduled at', backToSessions: 'Back to Sessions', sessionEnded: 'Session ended, redirecting...', sessionMissed: 'Session missed, redirecting...', loading: 'Loading...', error: 'Could not load session details.', }, }; export function SessionEndWaiting() { const { sessionId } = useParams<{ sessionId: string }>(); const navigate = useNavigate(); const { language } = useLanguage(); const { user } = useAuth(); const t = translations[language as 'ar' | 'en'] ?? translations.en; const isRTL = language === 'ar'; const [sessionData, setSessionData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [statusMessage, setStatusMessage] = useState(null); const intervalRef = useRef | null>(null); const handleTerminalStatus = (status: string, id: string) => { if (status === 'COMPLETED') { setStatusMessage(t.sessionEnded); navigate(`/session-report/${id}?mode=review`); } else if (status === 'MISSED' || status === 'CANCELLED') { setStatusMessage(t.sessionMissed); navigate(`/session-report/${id}?mode=review`); } }; const fetchSession = async (): Promise => { if (!sessionId || !user) return null; try { const token = localStorage.getItem('authToken'); const res = await fetch(`${getApiBaseUrl()}/api/student/sessions/${sessionId}`, { headers: { Authorization: `Bearer ${token}` }, }); if (!res.ok) return null; const data = await res.json(); return data.sessionStatus ?? data.status ?? null; } catch { return null; } }; // Initial load useEffect(() => { const init = async () => { if (!sessionId || !user) return; try { const token = localStorage.getItem('authToken'); const res = await fetch(`${getApiBaseUrl()}/api/student/sessions/${sessionId}`, { headers: { Authorization: `Bearer ${token}` }, }); if (!res.ok) throw new Error('not found'); const data = await res.json(); setSessionData(data); const status: string = data.sessionStatus ?? data.status ?? ''; // Immediate redirect if already terminal if (status === 'COMPLETED' || status === 'MISSED' || status === 'CANCELLED') { handleTerminalStatus(status, sessionId); return; } } catch { setError(t.error); } finally { setLoading(false); } }; init(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [sessionId, user]); // Polling useEffect(() => { if (loading || error || !sessionId) return; intervalRef.current = setInterval(async () => { const status = await fetchSession(); if (!status) return; // silently ignore failed polls if (status === 'COMPLETED' || status === 'MISSED' || status === 'CANCELLED') { if (intervalRef.current) clearInterval(intervalRef.current); handleTerminalStatus(status, sessionId); } }, POLL_INTERVAL_MS); return () => { if (intervalRef.current) clearInterval(intervalRef.current); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [loading, error, sessionId]); if (loading) { return (
{t.loading}
); } if (error || !sessionData) { return (

{error ?? t.error}

); } const scheduledDate = sessionData.scheduledStart ? new Date(sessionData.scheduledStart).toLocaleString(language === 'ar' ? 'ar-EG' : 'en-US', { weekday: 'short', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit', }) : ''; return (
{/* Animated pulsing ring */}
{t.title}

{t.subtitle}

{/* Session info */}
{t.with} {sessionData.sheikhName}
{scheduledDate && (
{t.scheduledAt} {scheduledDate}
)}
{/* Waiting message */}
{statusMessage ?? t.waitingMessage}
); }