"use client"; import { useCallback, useEffect, useState } from "react"; import { useParams, useRouter } from "next/navigation"; import { lmsApi, StudyRoom, BbbRecording } from "@/lib/api"; import { Video, Users, Clock, ExternalLink, ArrowLeft, RefreshCw, Film, ChevronDown, ChevronRight } from "lucide-react"; const STATUS_LABEL: Record = { pending: "Programada", active: "En curso", ended: "Finalizada", }; const STATUS_COLOR: Record = { pending: "bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-300", active: "bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300", ended: "bg-gray-100 text-gray-500 dark:bg-white/10 dark:text-white/40", }; export default function StudyRoomsPage() { const { id } = useParams() as { id: string }; const router = useRouter(); const [rooms, setRooms] = useState([]); const [loading, setLoading] = useState(true); const [joiningId, setJoiningId] = useState(null); const [error, setError] = useState(null); const [recordings, setRecordings] = useState>({}); const [loadingRec, setLoadingRec] = useState>({}); const [expandedRec, setExpandedRec] = useState>({}); const loadRooms = useCallback(async () => { setLoading(true); setError(null); try { const data = await lmsApi.listCourseStudyRooms(id); setRooms(data); } catch (e) { setError(e instanceof Error ? e.message : "No se pudieron cargar las salas"); } finally { setLoading(false); } }, [id]); useEffect(() => { void loadRooms(); }, [loadRooms]); const join = async (room: StudyRoom) => { setJoiningId(room.id); setError(null); try { const result = await lmsApi.joinStudyRoom(id, room.id); window.open(result.join_url, "_blank", "noopener,noreferrer"); void loadRooms(); } catch (e) { setError(e instanceof Error ? e.message : "No se pudo unir a la sala"); } finally { setJoiningId(null); } }; const activeRooms = rooms.filter((r) => r.status !== "ended"); const endedRooms = rooms.filter((r) => r.status === "ended"); const toggleRecordings = async (room: StudyRoom) => { const isExpanded = expandedRec[room.id]; setExpandedRec((prev) => ({ ...prev, [room.id]: !isExpanded })); if (!isExpanded && !recordings[room.id]) { setLoadingRec((prev) => ({ ...prev, [room.id]: true })); try { const recs = await lmsApi.getStudyRoomRecordings(id, room.id); setRecordings((prev) => ({ ...prev, [room.id]: recs })); } catch { setRecordings((prev) => ({ ...prev, [room.id]: [] })); } finally { setLoadingRec((prev) => ({ ...prev, [room.id]: false })); } } }; return (

Únete a sesiones en vivo con tu grupo

{error && (
{error}
)} {loading && rooms.length === 0 && (
)} {!loading && rooms.length === 0 && (
)} {activeRooms.length > 0 && (

Salas disponibles

{activeRooms.map((room) => (
{room.title} {STATUS_LABEL[room.status]}
{room.description && (

{room.description}

)}
Máx. {room.max_participants} participantes {room.started_at && ( {new Date(room.started_at).toLocaleString()} )}
))}
)} {endedRooms.length > 0 && (

Salas finalizadas

{endedRooms.map((room) => (
{room.title} {room.ended_at && ( Finalizada {new Date(room.ended_at).toLocaleDateString()} )}
{STATUS_LABEL.ended}
{expandedRec[room.id] && (
{loadingRec[room.id] ? (

Cargando grabaciones…

) : recordings[room.id]?.length ? (
{recordings[room.id].map((rec) => (
{rec.name} {rec.duration_minutes} min
Ver grabación
))}
) : (

No hay grabaciones disponibles.

)}
)}
))}
)}
); }